This Q is about using a FlowLayout. The lineup of labels and
textfields should be made in two horizontal rows by the size given in
the program. I tested this with 3 lightweight IDE's All use the same
jdk1.5.0_12.
With two of them, on a initial run, show no labels and textfields
items but the frame is in the correct size. If I open the screen to
the full width using the icon , all items are visible. If I then
click the icon to diminished size, using top of the frame menu bar,
all the items are there and in the intended line up. The third IDE
opens the program and right away everything is there in the correct
size and placement. Is the problem in the IDE's? Can the two that show
nothing on the initial run have a line of code added to make it appear
correct without resizing the screen manually from the app menu frame?
TIA
bH
Here's the program:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.text.SimpleDateFormat;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.imageio.*;
public class GoogleDrawImage
{
public static void main(String[] args)
{
JFrame frame = new ImageFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class ImageFrame extends JFrame implements ActionListener {
BufferedImage image;
JTextField
addressField,appendFieldcht,appendFieldchs,appendFieldchd,
appendFieldchm,appendFieldchf;
JLabel lbleGoogleInstr,lbleFieldcht,lbleFieldchs,lbleFieldchd,
lbleFieldchm, lbleFieldchf;
JButton btnGetGoogleApis,btnClose;
boolean isOneDone = false;
public ImageFrame()
{
super("Image from Developer's Guide - Google Chart API - Google");
super.setSize(800, 600);
Container con = getContentPane();
con.setLayout(new FlowLayout());
addressField = new JTextField(20);
addressField.setText("http://chart.apis.google.com/chart?");
appendFieldcht = new JTextField(8);
appendFieldcht.setText("r");
appendFieldchs = new JTextField(8);
appendFieldchs.setText("400x400");
appendFieldchd = new JTextField(8);
appendFieldchd.setText("t:70,70,70,70,70,70");
appendFieldchm = new JTextField(8);
appendFieldchm.setText("B,FF0000,0,0,5");
appendFieldchf = new JTextField(8);
appendFieldchf.setText("c,s,000000");
lbleGoogleInstr = new JLabel("Complete These to Get Drawing:");
lbleFieldcht = new JLabel("cht is: ");
lbleFieldchs = new JLabel("chs is: ");
lbleFieldchd = new JLabel("chd is: ");
lbleFieldchm = new JLabel("chm is: ");
lbleFieldchf = new JLabel("chf is: ");
btnGetGoogleApis = new JButton("GetGoogleApis");
btnGetGoogleApis.setActionCommand("GrabItAll");
btnGetGoogleApis.addActionListener(this);
btnClose = new JButton("Close Application");
btnClose.setActionCommand("close");
btnClose.addActionListener(this);
//Add Components to this container, using the default FlowLayout.
add (lbleGoogleInstr);
add(lbleFieldcht);
add (appendFieldcht);
add (lbleFieldchs);
add(appendFieldchs);
add(lbleFieldchd);
add(appendFieldchd);
add(lbleFieldchm);
add(appendFieldchm);
add(lbleFieldchf);
add(appendFieldchf);
add(btnGetGoogleApis);
add(btnClose);
image = null;
}
public void actionPerformed(ActionEvent e) {
String urlGoogleDrw = addressField.getText()+"cht="+
appendFieldcht.getText().trim()+"&chs=" +
appendFieldchs.getText().trim()+"&chd="+
appendFieldchd.getText().trim()+"&chm="+
appendFieldchm.getText().trim()+"&chf="+
appendFieldchf.getText().trim();
if (e.getActionCommand().equals("GrabItAll")) {
//nothing here so let it fall through and go on
}
else if (e.getActionCommand().equals("close")) {
System.exit(0);
}
try {
// Read from assembled URL
System.out.println(urlGoogleDrw);
URL url = new URL(urlGoogleDrw);
image = ImageIO.read(url);
} catch (IOException et) {
}
try {
Date dNow = new Date();
SimpleDateFormat formatter = new SimpleDateFormat
("yyMMddHHmmssZ");
String df = new String(formatter.format(dNow));
File file = new File("C:/Documents and "+
"Settings/bH/My Documents/BlueJ Projects/Viewer/imageDate "
+ df + " FromGoogle.png");
ImageIO.write(image, "png", file);
}
catch (IOException em) {
}
repaint();
}
public void paint(Graphics g)
{
g.drawImage(image, 50, 110, null);
if (isOneDone = false){
System.out.println("See C:/... " +
"/BlueJ Projects/Viewer/images/imageDate yyMMddHHmmssZ
FromGoogle.png");
isOneDone = true;
}
}
}
I compiled it and it displayed and ran. I don't use an IDE so I can't
help you there. It is possible that your problem is from not creating
the GUI on the EDT. And speaking of the EDT, you block it while
retrieving your image. Any change that would occur to the displayed
components will not happen until the EDT is freed. This may or may not
cause you to lose some of your GUI but the GUI will not be able to
respond until the image gathering code returns.
--
Knute Johnson
email s/nospam/knute2008/
--
Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
------->>>>>>http://www.NewsDemon.com<<<<<<------
Unlimited Access, Anonymous Accounts, Uncensored Broadband Access
>
> Here's the program:
...
> class ImageFrame extends JFrame implements ActionListener {
> public ImageFrame()
> {
> super("Image from Developer's Guide - Google Chart API - Google");
> //Add Components to this container, using the default FlowLayout.
> add (lbleGoogleInstr);
...
I don't see a call to pack() here....
> super.setSize(800, 600);
Call "setSize()" after pack(). I'd call "setSize()" not super.setSize()
although maybe you want to ensure that an over-ridden method is not
called... (I'd make the class final....)
> }
>
> bH wrote:
> > Hi All,
> >
> > This Q is about using a FlowLayout.
>[...]
> I compiled it and it displayed and ran. I don't use an IDE so I can't
> help you there. It is possible that your problem is from not creating
> the GUI on the EDT. And speaking of the EDT, you block it while
> retrieving your image. Any change that would occur to the displayed
> components will not happen until the EDT is freed. This may or may not
> cause you to lose some of your GUI but the GUI will not be able to
> respond until the image gathering code returns.
Knute's right about blocking. There's more here about perceived
performance when loading an image here:
<http://java.sun.com/docs/books/tutorial/uiswing/components/icon.html>
Also, I'm suspicious of overriding the JFrame's paint() method
(inherited from Container), without calling super.paint():
<http://java.sun.com/javase/6/docs/api/java/awt/Component.html#paint(java
.awt.Graphics)>
Absent that, I saw nothing until I tabbed through the fields.
To focus on the FlowLayout aspect of the code, I changed to a JPanel,
which uses FlowLayout by default. I also used an ImageIcon to contain an
image. Sorry, I'm not familiar with the Chart API:
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import javax.swing.*;
public class GoogleDrawImage
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new ImagePanel());
frame.setTitle("Google Chart API");
frame.setSize(600, 300);
frame.setVisible(true);
}
}
class ImagePanel extends JPanel implements ActionListener {
JTextField addressField, appendFieldcht, appendFieldchs,
appendFieldchd, appendFieldchm, appendFieldchf;
JLabel lbleGoogleInstr, lbleFieldcht, lbleFieldchs,
lbleFieldchd, lbleFieldchm, lbleFieldchf;
JButton btnGetGoogleApis, btnClose;
public ImagePanel() {
// Use default FlowLayout.
addressField = new JTextField(20);
addressField.setText("http://chart.apis.google.com...");
appendFieldcht = new JTextField(8);
appendFieldcht.setText("r");
appendFieldchs = new JTextField(8);
appendFieldchs.setText("400x400");
appendFieldchd = new JTextField(8);
appendFieldchd.setText("t:70,70,70,70,70,70");
appendFieldchm = new JTextField(8);
appendFieldchm.setText("B,FF0000,0,0,5");
appendFieldchf = new JTextField(8);
appendFieldchf.setText("c,s,000000");
lbleGoogleInstr = new JLabel("Complete these:");
lbleFieldcht = new JLabel("cht is: ");
lbleFieldchs = new JLabel("chs is: ");
lbleFieldchd = new JLabel("chd is: ");
lbleFieldchm = new JLabel("chm is: ");
lbleFieldchf = new JLabel("chf is: ");
btnGetGoogleApis = new JButton("GetGoogleApis");
btnGetGoogleApis.setActionCommand("GrabItAll");
btnGetGoogleApis.addActionListener(this);
btnClose = new JButton("Close Application");
btnClose.setActionCommand("close");
btnClose.addActionListener(this);
// Add Components to this container.
this.add(lbleGoogleInstr);
this.add(addressField);
this.add(lbleFieldcht);
this.add(appendFieldcht);
this.add(lbleFieldchs);
this.add(appendFieldchs);
this.add(lbleFieldchd);
this.add(appendFieldchd);
this.add(lbleFieldchm);
this.add(appendFieldchm);
this.add(lbleFieldchf);
this.add(appendFieldchf);
this.add(btnGetGoogleApis);
this.add(btnClose);
try {
ImageIcon icon = new ImageIcon(new URL(
"http://www.google.com/logos/olympics08_opening.gif"));
JLabel imageLabel = new JLabel(icon);
icon.setImageObserver(imageLabel);
this.add(imageLabel);
} catch (MalformedURLException e) {
System.err.println(e.toString());
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("close")) {
System.exit(0);
}
}
}
[I appreciate your sscce, but some might reasonably be wary of code that
reads from the network and writes to the file system.]
--
John B. Matthews
trashgod at gmail dot com
home dot woh dot rr dot com slash jbmatthews
Hi All,
Thanks for your responses. I have been unable to reconstruct the
program using panels. That rewrite of placing it on a panel makes none
of the labels and textfields appear reagrdless of which IDE I use. Yes
I did download John's sample above and it runs. but my adapting it to
my original one does not work. If I place the mouse over some of the
buttons they show up but nothing else shows up.
So I went back to my design written above with these revsions below.
In the original one above the button "GetGoogleApis" download the
image into the frame and immediately did a save. With a new revision
the button "GetGoogleApis" now it places it just in the frame, then
using a additional button "Save It" that image is now saved as a
image/file.png, if I so desire. Each button click is has a try and a
catch.
This is not a good programming example, too quirky.
bH
Do you intend to transform this code into a web app.
using the Google API? ..
>..I tested this with 3 lightweight IDE's All use the same
> jdk1.5.0_12.
..the reason I ask is that AFAIU, the Google API is
limited to Java 1.4.
But to the immediate problem.
1) When posting code, please make sure the lines are 'hard wrapped'
before news clients are forced to wrap the text. I provide TWC
to help with that. <http://pscode.org/twc/>
2) It is usually easiest to develop a GUI within a main (J)Panel,
that will be added to the content pane of a (J)Frame or (J)Applet
(or (J)Window or (J)Dialog or JOptionPane..).
3) When working with a JPanel, you would override paintComponent()
rather than paint().
4) Even when working with JPanels, I would not recommend trying to
mix laid out widgets *in* a custom painted panel. The best way to
approach that is to do the custom painting in an appropriately named
JPanel sub-class (e.g. MapPanel), and add the sub-class to the
main panel, along with the other controls in different layout
constraints of the main panel.
5) A FlowLayout is probably not appropriate for the type of layout
you seem to be attempting. A GridBagLayout might achieve the effect,
but I would probably try it as a nested layout. Since I am not
entirely sure of the layout/effect you want to achieve, or how the
space should be reassigned on resize, I will leave further speculation
on that, for the moment.
6) I think others have commented on blocking the EDT during
image download. It would be better to show a progress bar,
and allow the 'load' button to spring back after activation
(though you might disable it once a download starts, the
enable it once the image arrives).
--
Andrew Thompson
http://pscode.org/
> On Aug 8, 2:44 pm, "John B. Matthews" <nos...@nospam.invalid> wrote:
> > In article <489c6ec2$0$4045$b9f67...@news.newsdemon.com>,
> > Knute Johnson <nos...@rabbitbrush.frazmtn.com> wrote:
> >
> > > bH wrote:
> >
> > > > This Q is about using a FlowLayout.
> > >[...]
> > > I compiled it and it displayed and ran. I don't use an IDE so I can't
> > > help you there. It is possible that your problem is from not creating
> > > the GUI on the EDT. And speaking of the EDT, you block it while
> > > retrieving your image. Any change that would occur to the displayed
> > > components will not happen until the EDT is freed. This may or may not
> > > cause you to lose some of your GUI but the GUI will not be able to
> > > respond until the image gathering code returns.
> >
> > Knute's right about blocking. There's more here about perceived
> > performance when loading an image here:
> >
> > <http://java.sun.com/docs/books/tutorial/uiswing/components/icon.html>
> >
> > Also, I'm suspicious of overriding the JFrame's paint() method
> > (inherited from Container), without calling super.paint():
[...]
<http://groups.google.com/group/comp.lang.java.help/msg/bb2203c080c1b4e2?
hl=en>
[...]
> Thanks for your responses. I have been unable to reconstruct the
> program using panels. That rewrite of placing it on a panel makes none
> of the labels and textfields appear reagrdless of which IDE I use. Yes
> I did download John's sample above and it runs. but my adapting it to
> my original one does not work. If I place the mouse over some of the
> buttons they show up but nothing else shows up.
Yes, as documented: if I override paint in my code (above), I get the
same effect. If I call super.paint(), I don't:
public void paint(Graphics g) { super.paint(g); ... }
Instead, just have your button set the imageLabel's icon to whatever
image you get back from the server and call repaint():
public void actionPerformed(ActionEvent ae) {
String cmd = ae.getActionCommand();
if ("quit".equals(cmd)) {
System.exit(0);
} else if ("grab".equals(cmd)) {
try {
ImageIcon icon = new ImageIcon(new URL(
"<some valid chart url>"));
imageLabel.setIcon(icon);
imageLabel.repaint();
} catch (MalformedURLException e) {
System.err.println(e.toString());
}
}
}
> So I went back to my design written above with these revsions below.
Did you mean to post code below?
> [...] This is not a good programming example, too quirky.
Or that it's too quirky to post?
Hi All,
This is the corrected program fixing the errors
that I questioned about above. It is no longer
quirky.
Andrew, I have tried to limit it to the correct text
width. With the fix and the notes in place, it is no longer
a small program. I also tried to take the suggestions
of others to make it happen.
bH
The program:
/* demo taken from :
http://www.cs.stir.ac.uk/~sbj/examples/Java-applications
/DrawImageDemo/
With this program the user can adjust measures, colors
when downloading a pentagon shape from Google.
The Google Developers Guide site is:
http://code.google.com/apis/chart/
*/
import java.text.*;
import java.awt.image.*;
import java.net.*;
import java.util.Date;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.imageio.*;
import java.io.*; // For IOException
public class DrawImageCentered extends JFrame
implements ActionListener {
// Start up the application
public static void main(String args[]) {
DrawImageCentered app = new DrawImageCentered();
app.setSize(800,500); //explicitly sets the size
// app.pack(); // app.pack() makes the window
// exactly the right size for its laid out contents
app.setVisible(true);
} // main
private BufferedImage image;
private ClassLoader cl = getClass().getClassLoader();
// So we can load image resources
private JButton choice1 =
new JButton("Google Draw Image"),
choice2 = new JButton("Save Image"),
choice3 = new JButton("Close");
private JTextField addressField = new JTextField
("http://chart.apis.google.com/chart?"),
appendFieldcht = new JTextField("r"),
appendFieldchs = new JTextField("400x400"),
appendFieldchd = new JTextField("t:70,70,70,70,70,70"),
appendFieldchm = new JTextField("B,FF0000,0,0,5"),
appendFieldchf = new JTextField("c,s,000000");
private JLabel lblhttp = new JLabel ("http:"),
lblcht = new JLabel("cht:"),lblchs = new JLabel("chs:"),
lblchd = new JLabel("chd:"),lblchm = new JLabel("chm:"),
lblchf = new JLabel("chf:");
private MyCanvas thePicture = new MyCanvas();
// Widget for displaying the image
// Constructor: lays out the display
public DrawImageCentered() {
Container contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(lblhttp); contentPane.add(addressField);
contentPane.add(lblcht); contentPane.add(appendFieldcht);
contentPane.add(lblchs); contentPane.add(appendFieldchs);
contentPane.add(lblchd); contentPane.add(appendFieldchd);
contentPane.add(lblchm); contentPane.add(appendFieldchm);
contentPane.add(lblchf); contentPane.add(appendFieldchf);
contentPane.add(thePicture);
contentPane.add(choice1);
choice1.addActionListener(this);
contentPane.add(choice2);
choice2.addActionListener(this);
contentPane.add(choice3);
choice3.addActionListener(this);
} // DrawImage constructor
// actionPerformed: get picture to display and notify
// the canvas
public void actionPerformed(ActionEvent e) {
if(e.getSource() == choice1){ // get image from google
// address
String urlGoogleDrw = addressField.getText()+"cht="+
appendFieldcht.getText().trim()+"&chs="+
appendFieldchs.getText().trim()+"&chd="+
appendFieldchd.getText().trim()+"&chm="+
appendFieldchm.getText().trim()+"&chf="+
appendFieldchf.getText().trim();
try {
// Read from assembled URL
System.out.println(urlGoogleDrw);
URL url = new URL(urlGoogleDrw);
image = ImageIO.read(url);
thePicture.setImage(image);
}
catch (IOException em) {
System.out.println("import Data: I/O exception");
}
System.out.println
("Now press Save Image Button if you want to save it");
} //choice 1
if(e.getSource() == choice2){
try {
System.out.println("inside of Save it");
Date dNow = new Date();
SimpleDateFormat formatter = new SimpleDateFormat
("yyMMddHHmmssZ");
String df = new String(formatter.format(dNow));
File file =
new File("C:/Documents and Settings/bH/Desktop/"
+ df + " imageFromGoogle.png");
ImageIO.write(image, "png", file);
System.out.println
("finished writing, see Desktop file");
}
catch (IOException et) {
}
} //choice 2
if(e.getSource() == choice3){
System.exit(0);
} //choice 3
} // action draw picture
/* Class MyCanvas: to display a chosen image.
The image to be displayed is notified to this class by
calling its setImage method.
Constructor: only need to set up the size here,
so the layout manager knows
*/
class MyCanvas extends Canvas {
public MyCanvas() {
setBackground(Color.pink);
// This let us see how big the canvas is!
setSize(300,400);
} // MyCanvas constructor
private Image image; // The image on display just
//now (nothing initially)
// Set a new image to be displayed, and
// refresh the canvas on-screen
public void setImage(Image newImage) {
image = newImage;
repaint();
} // setImage
// And this actually draws the image, centered in
// the canvas
public void paint(Graphics g) {
if (image != null) {
// Make sure that there is an image
int xOffset = (getWidth()-image.getWidth(this))/2;
// x and y offsets to center the image in the
// canvas
int yOffset =
(getHeight()-image.getHeight(this))/2;
g.drawImage(image, xOffset, yOffset, this);
// Note: Coordinates relative to this Canvas widget
}
} // paint
} // class MyCanvas
}
I had to look through a lot of lines before I
understood you meant the code was OK to post!
> Andrew, I have tried to limit it to the correct text
> width.
Yes, good job, compiles and runs for me here.
Just reviewing the earlier spec. and trying to
understand some of the choices in that code.
Lack of call to pack() is a sure sign of trouble,
and when I pack() the GUI and it changes completely,
that is worse.
>..With the fix and the notes in place, it is no longer
> a small program.
166 lines is not too much for modern connections.
More (questions probably) later..
And as an aside..
...
app.setSize(800,500); //explicitly sets the size
//app.pack(); // app.pack() makes the window
// exactly the right size for its laid out contents
...
The point of X-plat (version, PLAF) development is
that we, the devloper cannot know what size the GUI
will end up being, since hopefully it adapts to their
screen size, default font size (+ all the stuff alluded
to above).
That is why we must rely on layout managers (usually
nested) to achieve the best layout component layout
in a resizable GUI.
That GUI as it appears for me (pre pack()), has a
lot of vacant space above and below the buttons, is
that intended?
(That appears odd to me - I would tend to stack them
down (GridLayout) in the EAST constraint of a BorderLayout.)
(I am still not entirely clear on how you would
like the components initially laid out, or where
to add/remove space if resized.)
Thank you for following up. Your program is much improved, although I
confess I changed the pink Canvas to a light gray and added a call to
clearRect() in paint(). Although FlowLayout is reliable, I hope you have
a chance to experiment with alternative layouts.
Inspired by your program, I offer another Google application: the
GoogleOlympiad!
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
/**
* @author John B. Matthews
*/
public class GoogleOlympiad
extends JPanel implements ActionListener {
private static final String prefix =
"http://www.google.com/logos/olympics08_";
private static final Border border =
BorderFactory.createMatteBorder(4, 16, 4, 16, Color.lightGray);
private static final Cursor defaultCursor =
new Cursor(Cursor.DEFAULT_CURSOR);
private static final Cursor waitCursor =
new Cursor(Cursor.WAIT_CURSOR);
private ArrayList<String> list = new ArrayList<String>();
private JLabel imageLabel = new JLabel();
private JButton quitButton = new JButton();
private ImageIcon image = new ImageIcon();
private JComboBox favorites;
public GoogleOlympiad() {
this.setLayout(new BorderLayout());
list.add("opening.gif");
list.add("cycling.gif");
list.add("weightlifting.gif");
list.add("diving.gif");
list.add("rhythm.gif");
list.add("rings.gif");
list.add("basketball.gif");
list.add("badminton.gif");
list.add("soccer.gif");
list.add("rowing.gif");
list.add("curling.gif");
JLabel titleLabel = new JLabel();
titleLabel.setText("The Google Olympiad");
titleLabel.setHorizontalAlignment(JLabel.CENTER);
titleLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
titleLabel.setBorder(border);
this.add(titleLabel, BorderLayout.NORTH);
image.setImageObserver(imageLabel);
imageLabel.setText("Select an image from the list below.");
imageLabel.setHorizontalAlignment(JLabel.CENTER);
imageLabel.setBorder(border);
this.add(imageLabel, BorderLayout.CENTER);
favorites = new JComboBox(
list.toArray(new String[list.size()]));
favorites.setActionCommand("favs");
favorites.addActionListener(this);
quitButton.setText("Quit");
quitButton.setActionCommand("quit");
quitButton.addActionListener(this);
JPanel controlPanel = new JPanel();
controlPanel.add(favorites);
controlPanel.add(quitButton);
controlPanel.setBorder(border);
this.add(controlPanel, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent ae) {
String cmd = ae.getActionCommand();
if ("favs".equals(cmd)) {
int index = favorites.getSelectedIndex();
imageLabel.setIcon(getImage(index));
}
if ("quit".equals(cmd)) {
System.exit(0);
}
}
private ImageIcon getImage(int index) {
this.setCursor(waitCursor);
try {
image = new ImageIcon(new URL(prefix + list.get(index)));
} catch (MalformedURLException e) {
System.err.println(e.toString());
}
if (image.getImageLoadStatus() == MediaTracker.COMPLETE) {
imageLabel.setText("");
} else {
imageLabel.setText("Image not available.");
}
this.setCursor(defaultCursor);
return image;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GoogleOlympiad());
frame.setTitle("Google Olympiad");
frame.setSize(400, 300);
frame.setVisible(true);
}
});
}
}
[Yes, I know curling is not featured!]