I need to change the direction of the growth of JTextField object when more characters are added to it. Currently when I add more stuff to it, it grows from left to right but I need this growth of the bounds of the JTextField from right to left.
For e.g. when I add "StackOverflow" to this JTextField the o/p is,
<empty space>StackOverflow
but I want,
StackOverflow<empty space>
Can you guys help me with this? I tried setHorizontalAlignment. But it doesnt work.
Thanks for any help.
EDIT : Added SSCCE for better explanation.
import java.awt.Container;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class JTextFieldExample {
public static void addComponentsToPane(Container pane) {
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
JTextField transitionEditorJTextField = new JTextField("StackOverFlow");
pane.add(transitionEditorJTextField);
System.out.println("If I add text to JTextFiled notice that it grows towards Right - which is normal. "
+ "But I want it to grow towards left.");
JButton button = new JButton("Button.I.Am");
pane.add(button);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("BoxLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
addComponentsToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
textField.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
I'm not sure I understand your question. Normally you create a JTextField with code like:
JTextField textField = new JTextField(10);
This gives the text field a fixed preferred size which is respected depending on the layout manager being used.
It sounds like you are doing something like:
JTextField textField = new JTextField();
In which case I don't think the text field has a size. Can you even add character to it? Well maybe the solution in this case is to add a ComponentListener to the text field and keep track of the original size. Every time the size changes you change the location of the text field by the difference in the size. Again this may or may not work depending on the layout manager.
If you need more help post your SSCCE showing the problem.
Related
This might be a very basic question. But I am stuck at this. The error that I get for the String variable display states:
Cannot refer to the non-final local variable display defined in an enclosing scope.
If I use a final keyword, I get the message:
The final local variable display cannot be assigned, since it is defined in an enclosing slope.*
The code is:
public class Frame {
public static void main(String[] args) {
String display=" ";
Frame ob=new Frame();
JFrame frame=new JFrame("Test");
frame.setBounds(300,100,800,500);
//Container c=frame.getContentPane();
frame.setLayout(null);
final JTextField name=new JTextField();
name.setBounds(500,212,150,20);
JLabel nameLabel=new JLabel("Name: ");
nameLabel.setForeground(Color.WHITE);
nameLabel.setBounds(450,171,100,100);
JTextField ohr=new JTextField();
ohr.setBounds(500,282,150,20);
JLabel ohrID=new JLabel("OHR ID: ");
ohrID.setForeground(Color.WHITE);
ohrID.setBounds(450,241,100,100);
final JButton button=new JButton("Submit");
button.setBounds(530,350,90,20);
frame.add(name);
frame.add(ohr);
frame.add(ohrID);
frame.add(nameLabel);
frame.add(button);
frame.getContentPane().setBackground(Color.DARK_GRAY);
frame.setVisible(true);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(e.getSource()==button){
display=name.getText();
JOptionPane.showMessageDialog(null, "Hi "+ display);
System.exit(0);
}
}
});
}
Thanks in advance!
There are multiple issues with your code, and we'll address them right here, right now and solve your problem at the same time.
public class Frame { this particular line has an error, Frame is the name of an AWT class, so it might confuse you or anyone who reads this code later on, give it a more meaningful name and avoid those names that could be confused with other Java packages.
Frame ob=new Frame(); you create an instance of your class and never use it again, why?
frame.setLayout(null); NEVER, please don't use null-layout, Swing has to deal with multiple PLAFs, screen sizes and resolutions, different OS, pixel perfect apps might seem like the easiest way to create complex UIs but later on you'll find that errors like this happen very often.
.setBounds(...) on every component, again, this is due to null-layout but it's better to use Layout managers
final JTextField name=new JTextField(); There's no need to declare any of your components as final, this is due to a poor design of your class, your components should be declared as class members (outside any method including main).
Speaking about main, separate your program into smaller pieces, don't throw everything at main or at the very least create a method that is not static so you can call it after creating an instance of your class (or else later on you'll end up with tons of static variables and that's a poor design of your class once again).
System.exit(0); it will stop the JVM, it's never a good idea to do that, it's better to .dispose() the JFrame and have your JFrame's defaultCloseOperation set to EXIT_ON_CLOSE which will safely dispose your app and then stop the JVM.
display=name.getText();, for this particular case, display could be an inner variable rather than a class member. This will solve your particular question
JOptionPane.showMessageDialog(null, "Hi "+ display); that null should be a reference to your JFrame, this will place your dialog in the middle of that JFrame rather than in the middle of the screen.
You never place your program inside the EDT, see point #2 in this answer.
So, having all the above points in mind, here's an improved version of your code.
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class UsingVariablesInsideActionListenerExample {
//We declare our components here
private JFrame frame;
private JButton button;
private JTextField name;
private JTextField ohr;
private JLabel nameLabel;
private JLabel ohrID;
private JPanel pane;
private JPanel namePane;
private JPanel ohrPane;
public static void main(String[] args) {
SwingUtilities.invokeLater(new UsingVariablesInsideActionListenerExample()::createAndShowGUI); //This is using Java 8 lambdas to place your program in the EDT
}
private void createAndShowGUI() {
frame = new JFrame("Test"); //Create your JFrame
pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS)); //This will make this JPanel to arrange components vertically
namePane = new JPanel(); //By default, JPanels have FlowLayout which will arrange components horizontally
ohrPane = new JPanel();
name = new JTextField(10); //We create a JTextField with 10 columns
nameLabel = new JLabel("Name: ");
nameLabel.setForeground(Color.WHITE);
ohr = new JTextField(10);
ohrID = new JLabel("OHR ID: ");
ohrID.setForeground(Color.WHITE);
button = new JButton("Submit");
//Add the action listener
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
String display = name.getText(); //The display variable is now an inner variable rather than a class member
JOptionPane.showMessageDialog(frame, "Hi " + display);
frame.dispose(); //We dispose the JFrame and it will be closed after due to EXIT_ON_CLOSE below.
}
}
});
//We add the components to the namePane (horizontally), the order matters
namePane.add(nameLabel);
namePane.add(name);
//Now we add these components to the ohrPane (horizontally again)
ohrPane.add(ohrID);
ohrPane.add(ohr);
//We then add the name and ohr panes to a bigger JPanel (pane, which if you remember will add them vertically) and we add the button at the end
pane.add(namePane);
pane.add(ohrPane);
pane.add(button);
//We make them non opaque (transparent) so that we can see the background color of the JFrame
namePane.setOpaque(false);
ohrPane.setOpaque(false);
pane.setOpaque(false);
frame.add(pane);
frame.getContentPane().setBackground(Color.DARK_GRAY);
frame.pack(); //This will get every component's preferred size and make the JFrame as small as possible where it looks good on every OS, PLAF, screen size and resolution.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true); //We make the frame visible (always at the very end, when we've added everything to it).
}
}
And this is how it looks like now.
The UI may not be perfectly equal to the one you have, but I'm sure you can play with the different layout managers, and nest various JPanels to get a much better looking UI than mine, or at least a more similar one to the one you had.
Variable used in side an inner class should be effectively final . You can use a string[] of length 1 instead of string to resolve this . Please read bellow post for more details
Difference between final and effectively final
Also check this post for more details
Variable used in lambda expression should be final or effectively final
So I have a layout made with buttons,textfields, and labels. A user is supposed to put input into the textfields. When he hits a button, I want it so that the input is cleared and a new "page" is shown with the layout i have made. The user can input as much information into new "pages" as he wants until he hits an "finished" button. In short, I want to switch between panels or frames (i dont know which, probably panels??). Now, I was thinking of using card layout to do this but since i'm reading user input it wouldn't really make sense since cardlayout is made based on a predetermined amount of panels and what will be in the panels. Since I won't know when the user is "finished", I won't know how many panels to use.
Anyways, I'm just a beginner with GUI so any help would be great!
Now, I was thinking of using card layout to do this but since i'm
reading user input it wouldn't really make sense since cardlayout is
made based on a predetermined amount of panels and what will be in the
panels. Since I won't know when the user is "finished", I won't know
how many panels to use.
You can dinamically add components to CardLayout on next button's click. If all the pages have the same structure you can have a class for those pages and add a new one every time next button is pressed. When finish button is pressed do something with all those pages iterating over the panel (with CardLayout) components. Take a look to Container.getComponents() method. You don't even need to keep any kind of array nor list because the container already do so.
Example
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Demo {
private void createAndShowGUI() {
final JPanel cardPanel = new JPanel(new CardLayout());
cardPanel.add(new Page(), "1");
final JButton nextButton = new JButton("Next");
nextButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardPanel.add(new Page(), String.valueOf(cardPanel.getComponentCount() + 1));
CardLayout layout = (CardLayout)cardPanel.getLayout();
layout.next(cardPanel);
}
});
final JButton finishButton = new JButton("Finish");
finishButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
nextButton.setEnabled(false);
for(Component comp : cardPanel.getComponents()) {
if(comp instanceof Page) {
Page page = (Page)comp;
page.printData();
}
}
}
});
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(nextButton);
buttonsPanel.add(finishButton);
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(cardPanel, BorderLayout.CENTER);
frame.getContentPane().add(buttonsPanel, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
class Page extends JPanel {
final private JTextField data;
public Page() {
super();
add(new JLabel("Please add some info:"));
data = new JTextField(20);
add(data);
}
public void printData() {
System.out.println(data.getText());
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}
As far as I understand from your description you do not need multiple panels. I am assuming that you have some sort of object hierarchy for your model layer. So, let's say you use those input values to create AnObject objects.
You can create an ArrayList<AnObject> in your top class. And as user inputs and clicks done you just create one more AnObject with given input and add it to the ArrayList you defined in top class.
BTW, you can also define ArrayList whereever it is reachable. But you must think carefully, to keep your data persistent. If the object of the class that you defined ArrayList is "gone", your data is also "gone". I think this should be clear enough.
The next step is just trivially clearing out those input fields.
This is the most straightforward way, it may not be the smartest way to do that depending on your use case. But it would give you an idea for what to look and learn for.
I have a frame, where i load a panel into. It works fine, but nothing has focus when it loads. Pressing tab doesn't help. I have to use the mouse to press a textfield.
I've tried: jtextfield1.requestFocus(); and jtextfiel1.requestFocusInWindow(); But it doesn't work.
What am I doing wrong?
The constructor in the JPanel:
public OpretOpdater(BrugerHandler brugerHandler, ReklamationHandler reklamationsHandler) {
initComponents();
jTextFieldOrdnr.requestFocusInWindow();
this.brugerHandler = brugerHandler;
this.rekH = reklamationsHandler;
startUp();
}
Putting the panel in the frame in the GUI:
public static void opret(ReklamationHandler reklamationHandler) {
rHandler = reklamationHandler;
SwingUtilities.invokeLater(opret);
}
static Runnable opret = new Runnable() {
#Override
public void run() {
JFrame f = jframe;
f.getContentPane().removeAll();
JPanel opret = new OpretOpdater(bHandler, rHandler);
f.getContentPane().add(opret);
f.pack();
f.setLocationRelativeTo(null);
}
};
You should call requestFocusInWindow() only when components are visible/shown on a container or after pack() has been called and all components are added to the container or else it wont work.
Also please be sure to create Swing components on Event Dispatch Thread. If you haven't already have read on Concurrency in Swing.
The reason I mention the above is not creating and manipulating Swing components on the EDT can cause random artifacts in the code. i.e focus is not being given etc.
This code below was created to show how calling requestFocusInWindow before a component is visible will not work but calling it after its visible works as expected.
Also note that removing the SwingUtilities block will cause the requestFocusInWindow not to work as expected (i.e we might be given focus or not depending on our luck :P):
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Test {
public Test() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JTextField f1 = new JTextField(10);
JTextField f2 = new JTextField(10);
//f2.requestFocusInWindow(); //wont work (if uncomment this remember to comment the one after setVisible or you wont see the reults)
JButton b = new JButton("Button");
JPanel p = new JPanel();
p.add(f1);//by default first added component will have focus
p.add(f2);
p.add(b);
frame.add(p);
//f2.requestFocusInWindow();//wont work
frame.pack();//Realize the components.
//f2.requestFocusInWindow();//will work
frame.setVisible(true);
f2.requestFocusInWindow();//will work
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {//if we remove this block it wont work also (no matter when we call requestFocusInWindow)
#Override
public void run() {
new Test();
}
});
}
}
I would suggest a read on How to Use the Focus Subsystem.
Often it is nice to indicate which field you want to have focus when you create the field and not separate the code by adding the request focus when the frame becomes visible.
Take a look at Dialog Focus which has a solution that is also applicable in this case. Using this approach your code would look like:
JTextField f2 = new JTextField(10);
f2.addAncestorListener( new RequestFocusListener() );
I am trying to make a box in Swing that has a label of "user", a text field for the username, and a button "sign in". This is my code
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class Engine
{
JFrame frame;
public void go()
{
setUpGui();
userNameScreen();
}
public void setUpGui()
{
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void userNameScreen()
{
JPanel background = new JPanel();
frame.getContentPane().add(background);
JLabel labelUserName = new JLabel("User:");
background.add(labelUserName);
System.out.println(labelUserName.getHeight()); // 0
JTextField textFieldUserName = new JTextField();
System.out.println(labelUserName.getHeight()); // 16
textFieldUserName.setPreferredSize(new Dimension(110,labelUserName.getHeight()));
background.add(textFieldUserName);
JButton buttonSignIn = new JButton("Sign In");
background.add(buttonSignIn);
/*
background.add(labelUserName);
background.add(textFieldUserName);
background.add(buttonSignIn);
frame.getContentPane().add(background);
*/
frame.pack();
}
}
My driver class just creates an instance of engine, then runs the method go().
I read that Swing components do not have attributes of height/width until they are added (because that is for the layout manager to decide how much room they have), so it makes sense that in the method userNameScreen(), adding in all components at the end* (commented out here) makes the textFieldUserName variable have no height.
However, you can see in that same method userNameScreen(), I have it do
System.out.println(labelUserName.getHeight());
twice. The first time, it is 0. The second, it is 16. I don't understand why the first time, it would register it as 0. It has already been added to the panel (in the line before), and there doesn't seem to be anything that would change its height between that first println() and the next. So why is the value 0 in the first one, and why does it change to 16 almost immediately after?
*I should note, when I say adding in all the stuff commented out at the end, it also includes removing/commenting out all the same commands done elsewhere in the code.
It is a side effect from not creating/modifying your Swing components on the EDT. Now the EDT is busy doing the layout while you are adding components in another thread.
Your main method should look like:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Engine().go();
}
});
}
I'm not sure why this is happening but may be because the addition of the component maybe on a background thread and might not have been updated till the next statement is called and its updated a few millisecs later and appears when you call it second time.
I'm having a problem that when my frame is shown (after a login dialog) the buttons are not on correct position, then in some miliseconds they go to the right position (the center of the panel with border layout).
-- update
In my machine, this SSCCE shows the layout problem in 2 of 10 times I run it:
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TEST {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
System.out.println("Debug test...");
JPanel btnPnl = new JPanel();
btnPnl.add(new JButton("TEST"));
JFrame f = new JFrame("TEST");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(btnPnl);
f.setPreferredSize(new Dimension(800, 600));
f.pack();
f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setVisible(true);
System.out.println("End debug test!");
}
});
}
}
The button first appers in the up-left, and then it goes to the center. Is it a java bug?
--update
Looks like the SSCCE don't show the problem for everyone that is trying.
Maybe it's my computer performance problem. I still think Java Swing is creating new threads for make the layout behind the scenes. But I'm not sure.
--update
The problem only occur with the f.setExtendedState(JFrame.MAXIMIZED_BOTH);
Your problem intrigued me. After some investigation I think I confirmed something that I recall about setting the window state (maximized, restored, etc) which is that setting the state is a request to the operating system and is left to the whim of the OS to process the request. This means it is asynchronous, or at least done later, after you set it. I confirmed using logging and adding resize listeners where you can see that the frame is resized after your block of code exits. Because of this, the pack() will layout components to their preferred size. So imagine the frame being sized to 800x600 and components positioned as such (button centered horizontally around 400). Then later, the OS changes the size of the frame to full screen (e.g. 1024x768) - for a moment, you'll see the button still at 400. Then the frame processes the new size and re-lays out components and centers the button at around 512. So you'll see the flicker as it transitions during this process. Perhaps a solution is to NOT pack() - it will remain at a size of zero and user will see minimum flicker.
Try this change first:
// pack()
If that looks good then you might have the next problem...if the user clicks the restore button, the whole frame shrinks into a black hole. So try calling pack AFTER the frame has been predictably resized due to the maximize. Something like this:
f.addComponentListener( new ComponentAdapter( ComponentEvent e ) {
public void componentResized( Component) {
if( f.getSize().getWidth() > 0 ) {
e.getComponent().removeComponentListener( this );
((JFrame)e.getComponent()).pack();
}
}
}
So if the user later clicks restore button the frame will have a nicely packed size ready to go.
--Update
OK, one last attempt. While I think my description of the problem has some truth, my solutions offered did nothing. Here's one last attempt. Remove pack() and setPreferredSize() and replace with setting the size to the screen size. This seems to reduce the flicker greatly on my system. This is because there should be no difference between the initial layout and the maximized layout done later. You can see this if you switch between restore and maximized. Although I still see a very slight flicker when switching the two, at least it seems to look better when first displayed.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TEST {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
System.out.println("Debug test...");
JPanel btnPnl = new JPanel();
btnPnl.add(new JButton("TEST"));
JFrame f = new JFrame("TEST");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(btnPnl);
// f.setPreferredSize(new Dimension(800, 600));
// f.pack();
f.setSize( Toolkit.getDefaultToolkit().getScreenSize() );
f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setVisible(true);
System.out.println("End debug test!");
}
});
-Mike
Maybe you are missing a frameThatContainsCentralPanel.pack()?
Well, if it works with a SSCCE, then you've proven the problem isn't with the basic logic. There must be something different between the SSCCE and your real code. Since we don't have access to your real code you need to do the debugging yourself to see what the difference is.
However, in this case a better solution is to use a CardLayout, which is designed to let you swap panels easily. Read the Swing tutorial for a working example.
Or anther approach is to use a "login dialog". Once the login is successfull, you display your main frame with the panel for your application.
I would guess that you need to call pack() before making your frame visible.
If you are calling the above code not on the event thread then you have a race condition and all bets are off - you can only manipulate the GUI from the EDT (event dispatch thread).
EDIT: I tried your SSCCE on my system and it is not exhibiting the behavior you are seeing. I tried it about 50 times, and also tried creating 10 windows by looping your code. I am running 1.6.0_18 on Windows XP SP3.
The "then in some milliseconds" part sounds to me like you need to call validate() on your frame. Also, if you use f.pack(), your panel needs a preferred size, because pack() gives the parent's components their preferred sizes and resizes based on them.
If I copied your code, I had the same problem, but not so heavy.
I solved it by setting a preferred size for your frame before packing. So:
import java.awt.Dimension;
System.out.println("Debug test...");
JPanel btnPnl = new JPanel();
btnPnl.add(new JButton("TEST"));
JFrame f = new JFrame("TEST");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(btnPnl);
f.setPreferredSize(new Dimension(800, 600));
f.pack();
f.setVisible(true);
System.out.println("End debug test!");
I'm running on Linux.
It is indeed strange... I'm sure it is something about the size of all the containers in the swing tree.
I would expect the frame to be maximised both before it is shown, but after checking this I'm sure that on linux frame is maximised after it has been displayed. You can make the frame size equal to a Screen size before calling setVisible, or you can make the components invisible until you know that the it's got preferred initial size. Here is modified sample which shows the elements after the frame has been activated (on linux activated event comes late enough to not show the "jumping button"):
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TEST {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
final JPanel btnPnl = new JPanel();
btnPnl.add(new JButton("TEST"));
final JFrame f = new JFrame("TEST");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(btnPnl);
// calculate preferred size for TEST frame
// f.isDisplayable() will become true
f.pack();
// extended state, if can be applied, needs to be called after f.isDisplayable()
WindowListener maxBoth = new WindowAdapter() {
#Override
public void windowOpened(WindowEvent e) {
f.setExtendedState(Frame.MAXIMIZED_BOTH);
}
};
// after windows has been opened - maximize both
f.addWindowListener(maxBoth);
// initially hide the elements
// after maximized state has been applied show them
f.getContentPane().setVisible(false);
f.addWindowListener(new WindowAdapter() {
#Override
public void windowActivated(WindowEvent e) {
f.getContentPane().setVisible(true);
// remove this listener
f.removeWindowStateListener(this);
}
});
// set the frame visible
f.setVisible(true);
}
});
}
}
Looks like a java bug. I've reported it (but for some reason it still not show on the bugs reports).