Currently I am calling a method (showFrames) which pops up a JFrame which contains many editable text fields. I am storing the value of these text fields in a list (editedFields) which I need to use in the calling method. My issue is that my calling method is not waiting for the user to select ok/cancel before continuing so the list is not populated when I am trying to take action on it. I tried to overcome this by using a modal dialog to no avail. the method is being called here...
...
showFrames(longToShortNameMap);
if (editedFields != null) {
for (JTextField field : editedFields) {
System.out.println(field.getText());
}
}
...
and the showFrames method is implemented as:
private static void showFrames(Map<String, String> longToShortNameMap) {
final ToolDialog frame = new ToolDialog("Data Changed");
frame.setVisible(true);
frame.setModal(true);
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(400, 500);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
JPanel panel = new JPanel(new GridLayout(0, 2));
JPanel buttonPanel = new JPanel(new GridLayout(2, 0));
List<String> keys = new ArrayList(longToShortNameMap.keySet());
final List<JTextField> textFields = new ArrayList<>();
for (String key : keys) {
JLabel label = new JLabel(key);
JTextField textField = new JTextField(longToShortNameMap.get(key));
panel.add(label);
panel.add(textField);
textFields.add(textField);
}
JButton okButton = new JButton("OK"); //added for ok button
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
editedFields = textFields;
frame.setVisible(false);
frame.dispose();
}
});
JButton cancelButton = new JButton("Cancel");//added for cancel button
cancelButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
frame.setVisible(false);
frame.dispose();
}
});
okButton.setVisible(true);//added for ok button
cancelButton.setVisible(true);//added for cancel button
buttonPanel.add(okButton);//added for ok button
buttonPanel.add(cancelButton);//added for cancel button
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setVisible(true);
scrollPane.setSize(500, 500);
frame.add(scrollPane, BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.SOUTH);
}
the current behavior I observe is that when the JFrame pops up, all the fields will immediately print out instead of waiting for the user to click "OK". Effectively this means I am receiving the default values in the text fields instead of the edited values.
Note: ToolDialog extends JDialog
The basic problem that you have is that you are instantiating the Dialog first, making it visible, and then adding fields to it.
That is essentially incorrect. All objects should be added to it while you are instantiating the Frame/Dialog, preferably in the constructor call. Then, you make it visible when everything is ready.
Of course, you can add a new field to the frame after showing it already, but that is typically done based on some event, for example, when user clicks "Add a new number", then you add new text fields, etc to it.
So, the fix for you is simple, move the logic that adds the buttons, the lists, the panels etc, to the constructor, and then make that window visible.
You have 2 different issues here :
Waiting for a dialog.
Displaying the dialog correctly.
1.- Waiting for a dialog.
You should use a JDialog instead of a JFrame to make the window modal.
The window is not modal because you are showing it before setting it to modal. See JDialog.setModal :
Note: changing modality of the visible dialog may have no effect until
it is hidden and then shown again.
You need to switch theese two lines :
frame.setVisible(true);
frame.setModal(true);
An alternate way is to synchronize with a countdown latch:
CountDownLatch latch = new CountDownLatch(1);
.......
showFrames(longToShortNameMap);
latch.await(); // suspends thread util dialog calls latch.countDown
if (editedFields != null) {
.......
/// Dialog code
latch.countDown(); // place it everywhere you are done with the dialog.
dispose();
2.- Displaying the dialog correctly.
Place frame.setVisible(true) as the last line of showFrames.
Related
"This method creates an object but does not assign this object to any variable or field. This implies that the class operates through side effects in the constructor, which is a bad pattern to use, as it adds unnecessary coupling. Consider pulling the side effect out of the constructor, into a separate method, or into the calling method."
This short test program runs as I expected, but I don't know how to address this checkstyle error. Most of the examples of using javax.swing seem to have this structure.
There is also a error causes by EXIT_ON_CLOSE, but without it the process lingers after I close the window and must be force quit.
public class GUI implements ActionListener {
private int clicks = 0;
private JLabel label = new JLabel("Clicks= " + clicks);
private JFrame frame = new JFrame();
public GUI() {
// make a Jbutton named button
JButton button = new JButton("Click Me");
button.addActionListener(this);
// arrange the button and label
JPanel panel = new JPanel();
panel.add(button);
panel.add(label);
// put the panel in a frame
frame.add(panel, BorderLayout.CENTER);
// EXIT_ON_CLOSE has a style error too.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Graphical User Interface");
frame.pack();
frame.setVisible(true);
}
// update label and number of clicks when button is clicked
public void actionPerformed(ActionEvent e) {
clicks++;
label.setText("Clicks= " + clicks);
}
// This is the code that InteliJ says has bad form.
public static void main(String[] args) {
new GUI();
} }
One bad pattern here is that you are not creating your GUI on Event Dispatch Thread. Not sure if this is related to your problem.. but you should always use EDT to create the GUI in Swing.
EDIT: take a look here. In the main method you just have "new GUI()" without a reference variable. Writing your app like this example you are not going to use the constructor to create all :)
I've read the similar questions regarding this problem, tried few methods but none is working.
I have 2 JFrame forms. I want to input information in the first form and submit it to the database. When I click a button, the second form will open and load the information
When I re-input new information in the first form and click the the button again, I want the second form to reload the new information inputted from the database.
This is my code so far.
time t = new time();
private void OrderButtonActionPerformed(java.awt.event.ActionEvent evt) {
if(t.isVisible()){
t.dispose();
t.revalidate();
t.repaint();
t.setVisible(true);
t.setLocationRelativeTo(null);
}
else{
t.setVisible(true);
t.setLocationRelativeTo(null);
}
You don't need to play with JFrames for that. See below example :
JLabel toe = new JLabel("I'm primary text");
JFrame cow = new JFrame("Primary Window");
JPanel cowpanel = new JPanel();
cowpanel.add(toe);
cow.setContentPane(cowpanel);
cow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
cow.pack();
cow.setVisible(true);
JButton tow = new JButton("Change");
tow.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
toe.setText("Hi!, I'm secondary text!");
}
});
JFrame dog = new JFrame("Secondary Window");
JPanel dogPanel = new JPanel();
dog.setContentPane(dogPanel);
dogPanel.add(tow);
dog.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
dog.pack();
dog.setVisible(true);
Clicking the 'Change' button from Frame 2 will change the JLabel's text in Frame 1.
I have an application which mainly uses a bot to press keys when a condition is met. I am used to working with applets so I am wondering about how the user stops the application. I did it by using the task manager but that is not very user friendly, is it?
So how can I make I UI for a standalone java application? Or is there an other way to give the user the opportunity to stop the application?
You need to add a button to the GUI, set an action listener to it and in the addActionListener call the System.exit() method..
Example:
JButton showDialogButton = new JButton("Exit the app");
showDialogButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
Do you have a JFrame?
If not Create a new JFrame, JPanel, and JButton with:
JFrame frame = new JFrame("title");
JPanel panel = new JPanel();
JButton button = new JButton("Close");
//You need this for the screen to show.
frame.setSize(width,height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
//add the panel to the frame and the button to the panel
frame.add(panel);
panel.add(button);
button.addActionListener(this);//the class needs to implements ActionListener
frame.setVisible(true);
//this is the actionperformed method which will run if the button is clicked.
public void actionPerformed(ActionEvent e) {
if(e.getSource==button){//If you have more than one button.
System.exit(0);
}
}
I want to create a JDialog which has a JTextField, this dialog box should start taking input from user no sooner it starts(i.e WITHOUT user having to click on it). I am calling the code using combination of key tap.So if any other app is running and I would want to pop this dialog box, i would just press the required keys.However currently, I have to click on the dialog box when it pops beacuse the present running app has the focus.Anyhelp..Thanks
//Creating a panel
JPanel panel = new JPanel( new SpringLayout() );
//creating a text field
final JTextField textfield = new JTextField(65);
// Modifying text field
Font font = new Font("SansSerif",Font.LAYOUT_LEFT_TO_RIGHT, 19);
textfield.setFont(font);
textfield.setForeground(Color.black);
textfield.setBackground(new Color(200,200,200,70)); //253,245,230
//border
textfield.setBorder(new BevelBorder(BevelBorder.LOWERED));
textfield.requestFocusInWindow();
//modifying panel
label.setLabelFor(textfield);
panel.add(textfield);
panel.setBackground(new Color(0,0,0,25));
panel.setPreferredSize(new Dimension(750,70));
panel.setBorder(new EtchedBorder(EtchedBorder.RAISED));
//Lay out the panel.
SpringUtilities.makeCompactGrid(panel,
1 , 2, //rows, cols
10, 10, //initX, initY
10, 10); //xPad, yPad
//Create and set up the Window Frame
final JDialog frame = new JDialog();
frame.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
//Positioning the dialog at the center of screen
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(dim.width/4-frame.getSize().width/4, dim.height/3-frame.getSize().height/3);
//Set up the content pane.
//adding background
frame.setLayout(new SpringLayout());
frame.setUndecorated(true);
frame.add(panel);
frame.setSize(750,71);
frame.repaint();
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
frame.toFront();
frame.setAlwaysOnTop(true);
frame.repaint();
frame.setVisible(true);
}
});
frame.addWindowFocusListener( new WindowAdapter() {
public void windowOpened( WindowEvent e ){
frame.requestFocus();
}
});
Almost every line of code is not needed or in the wrong order:
frame.pack();
frame.setSize(750,71);
Well, make up your mind what are you trying to do? The pack() method is used to have the frame automatically calculate the size based on the components added to the frame. The setSize() would override the results of the pack() method. You should only pack() the frame AFTER adding all the components to the frame.
frame.repaint();
No need for the repaint(), the setVisible(true) method will make sure the frame is painted.
frame.requestFocus();
Not needed, when the frame is made visible focus will automatically go to the first component.
So the basic order of your code should be something like:
JTextField textField = new JTextField(20);
JFrame frame = new JFrame(...);
frame.add(textField, BorderLayout.PAGE_START);
frame.pack();
frame.setVisible(true);
There is no need to request focus on the text field. Focus will automatically be placed on the first component.
You may also want to take a look at the Swing tutorial on How to Make Dialogs. You can use a JOptionPane to prompt a user for text input. The tutorial has working examples.
field = new JTextField(40);
f.addWindowListener( new WindowAdapter() {
public void windowOpened( WindowEvent e ){
field.requestFocus();
}
});
What are you doing here?
There is no textfield show in your code. All you have is a dialog... Do you need help making a textfield? How to add components to JDialog
Then after you make a text field select it by using textField.requestFocusInWindow()
or look at this post to help, Java Textfield focus
I am trying to open a GUI from my main GUI by pressing a button. When the button is pressed, this is executed:
WorkloadFactor wf = new WorkloadFactor();
wf.setVisible(true);
This doesn't open the WorkloadFactor GUI. I am confused by this because I have other GUIs that open this way without issue.
WorkloadFactor class works fine when I run it by itself but won't open when it is called by my main GUI. Below is my class without imports and stuff:
public class WorkloadFactor extends JPanel {
public WorkloadFactor() {
setLayout(new BorderLayout());
JTabbedPane tabbedPane = new JTabbedPane();
String[] tabnames = { "Zero", "One", "Two", "Three", "Four" };
for (int i = 0; i < tabnames.length; i++) {
tabbedPane.addTab(tabnames[i], createPane(tabnames[i]));
}
tabbedPane.setSelectedIndex(0);
JButton submit = new JButton("Submit All");
submit.setForeground(Color.RED);
add(tabbedPane, BorderLayout.CENTER);
add(submit, BorderLayout.SOUTH);
}
public JPanel createPane(final String t) {
JPanel contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
//setContentPane(contentPane); I think this might be it?
contentPane.setLayout(null);
setBounds(100, 100, 531, 347);
//***** all the components I am including then add them like so
//******contentPane.add(checkbox1);
//****** contentpane.add(label1);
return contentPane;
}
public static void main(String[] args) {
JFrame frame = new JFrame("Set Workload Factor Information");
frame.getContentPane().add(new WorkloadFactor());
frame.setBounds(100, 100, 531, 347);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
I have tried arranging things in so many ways, putting everything in the constructor and other changes but can't seem to find a reason why instantiating this WorkloadFactor class elsewhere and setting it visible won't work.
Does it have something to do with setContentPane(contentPane) vs contentPane.add(xxxx) and returning it?
Thank you for reading!
WorkloadFactor wf = new WorkloadFactor();
wf.setVisible(true);
To be blunt, this won't display anything. Please understand that WorkloadFactor extends JPanel and like all non-top level components must be placed into a container that is ultimately held by a top-level window in order to be displayed. Look at how you display it in your main method -- you first put it into a JFrame, and then display that JFrame. You must do the same thing if you want to display it on button press -- you need to put it into a JPanel or other container that is held by a JFrame or JDialog, or JOptionPane.
Make sure that you have properly registered the button on your main GUI which opens WorkLoadFactor GUI to an action listener.
Since you have not included code from your main GUI I can't confirm this is the issue. However it is a commonly overlooked issue.
Heres some suggestions from the Java documentation tutorials:
"Problem: I'm trying to handle certain events from a component, but the component isn't generating the events it should.
First, make sure you registered the right kind of listener to detect the events. See whether another kind of listener might detect the kind of events you need.
Make sure you registered the listener on the right object.
Did you implement the event handler correctly? For example, if you extended an adapter class, then make sure you used the right method signature. Make sure each event-handling method is public void, that the name spelled right and that the argument is of the right type."
source: Solving Common Event-Handling Problems
Make a JFrame and add a JButton in it than add action listener in button and add this code in it like this:
This code makes a frame with a button and when button is pressed new window is opened.
public class Example extends JFrame {
public Example() {
super("Title");
setLayout(new FlowLayout());
JButton b = new JButton("Open new Frame");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
newWindow nw = new newWindow();
}
});
add(b);
}
}
newWindow Code:
public class newWindow extends JFrame {
newWindow() {
super("title");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,400);
setVisible(true);
}
}