I've only just begun writing GUI programs, this being my second one. With both projects (both homework assignments) I have had the same issue. The GUI objects (such as JTextField) do not show when the application runs until after I resize the window or move keyboard focus to them. If I do not do one of those two things, then I'll just have an empty application window.
Any ideas why this is happening and what I could do to solve it? I'm working on Mac OS 10.6.1.
My code is below. Feel free to comment on my coding style, but please focus on the problem I'm having.
import javax.swing.*;
import java.awt.*;
public class ToDo extends JFrame {
private int height = 30,
width = 300;
public ToDo() {
this.setSize(400,400);
this.setVisible(true);
this.setLayout(null);
this.setResizable(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("To Do List");
JTextField todoItem[] = new JTextField [10];
Container contentpane = this.getContentPane();
contentpane.setLayout(null);
for(int i=0; i<10; i++) {
todoItem[i] = new JTextField();
todoItem[i].setBounds(10,(height*(i)+10),width,height);
contentpane.add(todoItem[i]);
}
}
public static void main(String[] args) {
new ToDo();
}
}
You have to add the elements before the component is made visible.
Put this as your last line:
this.setVisible(true);
alt text http://img10.imageshack.us/img10/8210/capturadepantalla200911s.png
This is not OSX related, it happens in Windows also.
There are some rules about how you should never touch Swing objects from outside the Swing thread once they've been realized. I always ignore these rules, but it could well be you've been bitten by them under Mac OS.
As a step in the officially right direction, try to not do setVisible() until you've assembled the whole thing, i.e. at the bottom of the constructor.
Reference material: http://www.math.vu.nl/~eliens/documents/java/tutorial/ui/swing/threads.html
A guess: add the component before setBoundsing it.
I could be wrong--been a long time since I've done a GUI in java--but I'm guessing your issue is making the JFrame visible before you finish adding elements. I think you need to either do that afterwards, or call update on the frame.
EDIT - Also, not sure setting the layout to null is a good idea. I've always used GridBag, but it might lose its default if you set it to null.
Related
I'm very new to Java but have some experience with C++. This is a homework assignment so I'm really just looking for someone to point me in the right direction.
The assignment requires a JFrame with JPanel objects displaying every card in a deck in a 13x4 grid. The Professor has supplied us with some code to get us started:
import javax.swing.*;
import java.awt.*;
public class Main
public static void main(String[] args)
{
//load the card image from the gif file.
final ImageIcon cardIcon = new ImageIcon("cardImages/tenClubs.gif");
//create a panel displaying the card image
JPanel panel = new JPanel()
{
//paintComponent is called automatically by the JRE whenever
//the panel needs to be drawn or redrawn
public void paintComponent(Graphics g) {
super.paintComponent(g);
cardIcon.paintIcon(this, g, 20, 20);
}
};
//create & make visible a JFrame to contain the panel
JFrame window = new JFrame("Title goes here");
window.add(panel);
window.setPreferredSize(new Dimension(200,200));
window.pack();
window.setVisible(true);
}
}
I have tried out a few things, but I can't seem to get multiple panels to display. Should I use a gridLayout() feature? or just create multiple panels and specify each one's location in the frame?
Again if someone can just point me in the right direction that would be awesome.
For displaying elements at the same size, evenly distributed within the container, then yes, GridLayout would be a good choice.
If you need to display the components in the grid at there preferred size (which may be different for each component) then GridBagLayout would be a better choice
If the code was supplied by a your professor, then you need to go back and make them fix it.
Firstly, a JLabel would be easier and provide better support for what you are trying to achieve...
Secondly, because the JPanel doesn't override getPreferredSize, most of the layout managers will set the size of the component to 0x0
There is a way to display multiple JPanels in one JFrame. Unlucky you the way is not so easy. Java has many diffrent LayoutManagers.
For your purpose I would recommend GridBagLayout, it is more complex, but definately the thing you need.
Here is a good tutorial, which helped me to understand it:
GridBagLayout
Hope it is a help.
I'm working on an online mode for a new game and in order to prevent cheating I need fix window sizes (and both players need a window with the same sizes).
I used 'jframe.setResizable(false);' but it seems to be "glitchy".
When I click the window and move it away from the border of the screen, Windows does minimize it.
Here's a video about it:
http://www.youtube.com/watch?v=AQ7OHJOuLSk&feature=youtu.be
I've tried following code in order to fix it:
Dimension d = new Dimension(width, height);
panel.getJFrame().setMaximumSize(d);
panel.getJFrame().setMinimumSize(d);
panel.setMaximumSize(d);
panel.setMinimumSize(d);
and I created a Component Listener:
if (max_height!=-1){
if (e.getComponent().getSize().getHeight()>max_height){
e.getComponent().setSize((int) e.getComponent().getSize().getWidth(),max_height);
}
}
if (max_width!=-1){
if (e.getComponent().getSize().getHeight()>max_width){
e.getComponent().setSize(max_width,(int) e.getComponent().getSize().getHeight());
}
and I tried to work with Layouts but nothing worked.
What I need now is either the possibility to prevent that minimize "glitch" (If it is a glitch) or a way to make the JPanel not resizable. Like when the size of the JFrame window is changed, the JPanel always stays the same. It's neither streched nor minimized.
Help is much appreciated :)
Sincerely Felix
So far the best patch for this annoying issue is the following. Doesn't matter where you call the setResizable(false) method. Just add this piece of code after you setVisible(true).
private void sizeBugPatch() {
while (frame.getWidth() > yourWidth) {
frame.pack();
}
}
Where yourWidth is the width you've set in any of the possible ways, either manually or by overriding setPreferredSize methods. The explanation is quite easy, frame.pack() seems to reset frame.setResizable(boolean b) somehow. You could use an if instead of the while loop but I prefer while to exclude the case the window would still be extra-sized even after a second pack().
Did you initialize the variable jframe or are you calling the general Class?
Because if you do it like this:
JFrame frame = new JFrame();
frame.setResizable(false);
It works fine for me...
I'm trying to create a 50x50 window in Java but the window won't go smaller than 125x50, even if I try to manually resize it.
Here's my code currently:
import javax.swing.*;
public class smallwindow {
public static void main(String args[]) {
JFrame frame = new JFrame("");
frame.setSize(50, 50);
frame.setVisible(true);
}
}
I am running this with the latest version of Java on Mac OS X.
Is there any way to do this with a JFrame, or would I need to use something else, like maybe AWT?
**edit: is there a way to do this while retaining the titlebar, window management buttons, etc.?
You would have to do the following on the JFrame:
frame.setUndecorated(true);
Guys, I did a little more looking into it, apparently there is a method called setMinimumSize
Basically, all you need to do is add
Dimension minimumSize = new Dimension(50, 50);
frame.setMinimumSize(minimumSize);`
I've found that if the size is less than about 75x75, then resizing it will suddenly change the minimum width to around 75. The solution is to just to do frame.setResizable(false)
But anyways, thanks for all your help!
but is there anyway to do this such that you still retain the tilebar, window management buttons, etc.?
You can use the Metal LAF which includes the title bar:
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame(...);
I am teaching myself Java and I am reading "Java All in One Desk Reference For Dummies." I am currently using the code provided in the book to practice Swing. Here is the code I am using that comes from the book: `import javax.swing.*;
public class JavaBook6 extends JFrame
{
public static void main(String[] args)
{
new JavaBook6();
}
public JavaBook6()
{
this.setSize(400, 400);
this.setLocation(500, 0);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle("Sample");
this.setVisible(true);
JPanel pnlMain = new JPanel();
JCheckBox chkMy = new JCheckBox("Save");
JButton btnMy = new JButton("Search");
JTextField txtMy = new JTextField(20);
pnlMain.add(chkMy);
pnlMain.add(txtMy);
pnlMain.add(btnMy);
this.add(pnlMain);
}
}
I seem to get inconsistent results when I press run. A window always shows up. However, sometimes the only thing displayed in the window is the Frame title and other times the components such as JCheckBox, JTextArea and JButton show up, as I would expect.
My question is why do the components show up sometimes and not others? I have tried using other components and get the same inconsistent results.
As I stated I am a beginner and I therefore have a very basic understanding of how java works, so please forgive me if the answer to my question is obvious.
I'm not too impressed with the text book:
The GUI should be created on the EDT. Read the section from the Swing tutorial on Concurrency for more information. I would also recommend you use the examples from the tutorials since they incorporate the suggestions from the tutorial.
Component must be added to the GUI before the setVisible( true ) method is invoked. (There are ways around this, but for now keep it simple and follow this rule).
You generally need to do...
this.pack();
before it will display everything.
I suspect if you resize the window, everything shows up?
Adding the pack() tells the layout manager to position and size all the components.
Also if you resize the window or force it to refresh in some way it will also display the components.
Sorry about this question but I have been struggling with an assignment my professor gave us for days and have no idea where to begin. I don't want someone to do it for me or anything, I am just looking to learn/get some good pointers because I can't find a foothold in this at all.
The assignment is as follows :
Implement a graphical user interface with the GridLayout class with a 10 5 grid of JButtons and JLabels. The JButtons should be on the top five rows and the JLabels should be on the next five rows. (The first JButton should have the text 1-1 and the last the text 5-5.) The JButton on the i th row and j th column should have the text i - j on it. The text of the JLabels should be 0.
The purpose of the JLabels is to count the clicks of the corresponding JButtons. For example, when a user clicks button
i - j for the first time, the text of the JLabel of the (5 + i )th row and j th column should change to 1.
You are not allowed to use any instance variables.
Hint 1: use and inner class for the labels.
Hint 2: you can increment the “number” the label by getting the text of the label, parsing it to an int with Integer.parseInt( ), and by changing the text of the label.
You must also add one more JButton which resets the counters on the JLabels. The
text on the JButton should be reset.
So far I have just been studying notes with no understanding or cluelessly typing away and come up with a completely non-functioning desperate attempt which is as follows :
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class NewFrame extends JFrame {
private static JButton[] buttons;
public static void main ( String[] args ) {
NewFrame frame = new NewFrame( );
}
public void NewFrame( ){
JFrame frame = new JFrame ("JFrame");
JPanel panel = new JPanel( );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
int noOfButtons = 25;
buttons = new JButton[ noOfButtons ];
for(int i = 0; i<buttons.length ; i++){
buttons[i] = new JButton();
panel.add(buttons[i]);
JLabel label = new JLabel( "Initial Text" );
}
frame.getContentPane( ).add( panel );
frame.setSize( 500, 500);
frame.setVisible( true );
}
}
Can someone please offer me some advice or hints here as I have been struggling with this for an age ?
Please have a look at this link: So, You Need to Write a Program but Don't Know How to Start which will give you great tips on how to start. The key is to break down your big problem into small steps and then try to solve each step in isolation. Then if you get stuck at least you'll be able to post a much more specific question, one that is more easily answered with a specific and helpful answer. Another good resource are the Swing tutorials which can show you how to use the various Swing components including JFrames, JPanels, JButtons, text components, and what not. You can find them here: Using Swing Components
Best of luck!
Edit 1:
Your code now compiles but there are two glaring issues that first need to be fixed:
1) Your class has no constructor but rather a "pseudo-constructor". Remember constructors have no return type, not even void.
2) You don't use a GridLayout.
Other issues: again the key is to break the problem down. I recommend you do just that on paper, and then type your version of the steps you think you need to solve the problem. Then we can go through them one at a time.
Generally, when you write a Swing application, your main class extends JFrame. You do all the initialization / create the buttons / etc in the constructor, then create an instance of the class in main()
-- edit --
see hovercraft's comment - you don't have to do the following in the constructor of an extended JFrame. Just change this to your JFrame variable if you do it externally.
The java documentation is your best friend - use it. http://download.oracle.com/javase/6/docs/api/
Create a GridLayout object, assign it to your content pane (this.getContentPane()) with setLayout
Create your buttons / labels, add those to the content pane
etc, etc
Look at the documentation for JButton.setActionCommand, JButton.addActionListener
You can access the labels later to increment / reset them with this.getContentPane().getComponents(), or one of the other access methods
Before I look at the code, you will surely need the Java tutorials on buttons and actions:
http://download.oracle.com/javase/tutorial/uiswing/components/button.html
http://download.oracle.com/javase/tutorial/uiswing/misc/action.html
The first issue with your code is that you use an instance variable to store the buttons in an array. You don't need this, since you are already adding them to the panel immediately.
The second issue is actually getting your buttons to do stuff when clicked. You need to add an ActionListener of your own design to each button, as follows:
myButton = new JButton();
myButton.addActionListener(new MyButtonListener());
and declare some MyButtonListener:
public class MyButtonListener implements ActionListener
{
}
the contents of the ActionListener class are beyond the scope of my help for your homework. But the Java tutorials are a great resource if you have no idea how to implement ActionListener.