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);
}
}
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 have a simple swing App, that can manage a specific type of project with multiple JButton and that print the project tree on the bottom, see the screenshoot bellow when a project is opened in the App :
App screenshoot with project opened
The thing is when no project is opened I get something like this :
App screenshoot without project opened
The HMI is simple and looks like this :
public class Desktop extends JFrame implements ActionListener {
public Desktop() {
JButton newProject, generate, quit, bAddToClassPath, openProject, saveProject;
JPanel mainPanel;
JScrollPane jscrollpane;
super("MainWindow");
setLookAndFeel();
setSize(330, 440);
ParamMainPanel();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Desktop();
}
});
}
public static void ParamMainPanel() {
mainPanel = new JPanel(new FlowLayout());
// BUTTONS PARAM
newProject = new JButton("Nouveau projet");
generate = new JButton("Générer...");
quit = new JButton("Quitter");
openProject = new JButton ("Ouvrir projet");
saveProject = new JButton ("Sauvegarder");
bAddToClassPath = UIUtil.iconButton();
bAddToClassPath.setActionCommand("setCP");
bAddToClassPath.addActionListener(this);
mainPanel.add(bAddToClassPath);
newProject.addActionListener(this);
newProject.setActionCommand("newP");
generate.addActionListener(this);
generate.setActionCommand("gen");
quit.addActionListener(this);
quit.setActionCommand("qui");
openProject.addActionListener(this);
openProject.setActionCommand("openP");
saveProject.addActionListener(this);
saveProject.setActionCommand("save");
mainPanel.add(newProject);
mainPanel.add(generate);
mainPanel.add(openProject);
mainPanel.add(saveProject);
mainPanel.add(quit);
// PROJECT TREE
jscrollpane = new JScrollPane(new JTree());
jscrollpane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jscrollpane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
jscrollpane.setMinimumSize(new Dimension(50, 50));
jscrollpane.setLocation(4,61);
jscrollpane.setSize(306,322);
mainPanel.add(jscrollpane);
}
}
So what I want is at the App launch, instead of having the bad looking display JTree (into the jscrollpane) without project opened, having the same display with a project opened (white bloc) but without the project tree inside.
I can't figure how to do it, any ideas ?
Here the answer I found to resolve this display problem :
The FlowLayout used on my main panel somehow was preventing me from resizing my jscrollpane directly using setSize()
So I decided to have a secondary panel on my MainFrame secondMainPanel without specific layout using new JPanel(null);
I did add jscrollpaneon it, then I could resize it without problems to have a correct display.
I think there might be better way to fix it, but this one works.
public class Create_JFrame extends JFrame{
public Create_JFrame(){
//Create a Frame
JFrame Frame = new JFrame("Bla-Bla");
JPanel Panel_1 = new JPanel();
JPanel Panel_2 = new JPanel();
JButton Option_1 = new JButton("Option-1");
//Layout management for Panels
Frame.getContentPane().add(BorderLayout.WEST, Panel_1);
//Add button to Panel
Panel_1.add(Option_1);
//Registering Listeners for all my buttons
Option_1.addActionListener(new ListenerForRadioButton(Panel_2));
//Make the frame visible
Frame.setSize(500, 300);
Frame.setVisible(true);
}//end of Main
}//end of Class
public class ListenerForRadioButton implements ActionListener{
JPanel Panel_2;
JButton browse = new JButton("Browse");
//Constructor, will be used to get parameters from Parent methods
public ListenerForRadioButton(JPanel Panel){
Panel_2 = Panel;
}
//Overridden function, will be used for calling my 'core code' when user clicks on button.
public void actionPerformed(ActionEvent event){
Panel_2.add(browse);
System.out.println("My listener is called");
}//end of method
}//end of class
Problem Statement:
I have 2 JPanel components in a a given JFrame. Panel_1 is having a Option_1 JButton. When user clicks on that I am expecting my code to add a JButton 'browse' in Panel_2 at runtime.
Runtime Output:
System is not adding any JButton in Panel_2. However, I see my debug message in output, indicating that system was successful in identifying user's click action on 'option-1'.
Question:
Why is JPanel not adding any component at Runtime?
Panel_2.add(browse);
Panel_2.revalidate();
adding a 'revalidate' will solve the problem.
There are some reasons. but:
usually it's because of using unsuitable LayoutManager.
sometimes it's because of adding the JPanel to it's root component in worng way. which any operation (add, remove,...) works but is not visible.
you must refresh the view when you make some changes on it, like adding or removing components to/from it.
try to use Panel_2.revalidate() to refresh.
if it doesn't work properly use it with Panel_2.repaint() method.
see Java Swing revalidate() vs repaint()
see Difference between validate(), revalidate() and invalidate() in Swing GUI
using setSize twice for your jframe is another way.
Frame.setSize(498, 300); then Frame.setSize(500, 300);
I am new to java and am getting to the advanced level of it, i have a problem in the GUI Controls, i made a button that when clicked opens up a new window like this:
JButton b = new JButton("Open New Window");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Window w = new Window();
w.setVisible(true);
}
});
this window contains other objects but i have been thinking of making the button in such a way that instead of opening a new JFrame, it opens everything in that same window without opening a new window, honestly i dont know how to do so please could i get some professional help
I think you want a card layout for this situation. Here is some code which should point you in the right direction.
class MyFrame extends JFrame {
public MyFrame() {
JComponent allMyStuff = new JComponent();
JComponent allMyOtherStuff = new JComponent();
this.getContentPane().setLayout(new CardLayout());
this.getContentPane().add(allMyStuff, "1");
this.getContentPane().add(allMyOtherStuff, "2");
CardLayout cl = (CardLayout) (this.getContentPane().getLayout());
cl.show(this.getContentPane(), "1");
JButton b = new JButton("Open New Window"); //add somewhere to first compoonent
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
CardLayout cl = (CardLayout) (this.getContentPane().getLayout());
cl.show(this.getContentPane(), "2");
}
});
}
}
I doubt the code runs but generally it holds the idea. You have stuff in one panel, and stuff in another panel, and you just want to switch between the two. The button of course needs to be added in the first panel (allMyStuff) somewhere.
I"m not clear on what it is exactly that you want to show in the GUI when the button is pressed, but perhaps you should consider creating different JPanel "views" and swap these views in the GUI using a CardLayout.
For example, check out these StackOverflow questions and answers:
Java CardLayout Main Menu Problem
Change size of JPanel using CardLayout
Java CardLayout JPanel moves up, when second JPanel added
Java swing; How to toggle panel's visibility?
Clear components of JFrame and add new componets on the same JFrame
gui multiple frames switch
JLabel displaying countdown, java
Within the action listener that you have introduced, you have the possibility to access to instance variables. Therefore you can add further elements to your GUI if you want. I've done a small demo, maybe this is kind of, what you want to do. In order to make your GUI better, you should consider of using layout managers.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class GUI {
JFrame frame;
JButton btn;
JButton compToAdd;
public GUI() {
frame = new JFrame("Testwindow");
frame.setSize(500, 500);
frame.setLayout(null);
btn = new JButton("test btn");
btn.setBounds(20, 20, 200, 200);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
compToAdd = new JButton("new Button");
compToAdd.setBounds(20, 220, 200, 200);
frame.add(compToAdd);
frame.repaint();
}
});
frame.add(btn);
frame.setVisible(true);
}
public static void main(String[] args) {
GUI gui = new GUI();
}
}
I've looked at other JLabel threads and though similar, a few just don't seem to apply to what I'm experiencing. First, I want to say I am a novice when it comes to Java. Next, I am trying to follow tutorials and demos at the docs.oracle.com site. Now, I can update the label when I type something into a JTextField and there is an ActionListener on that...
But I also have a Menu, and when I select a Menu Item, that Action does not want to update the label.
Questions -
How do I have action listeners on both JTextFields and JMenuItems? Are there two ActionEvent methods or do I use one method and somehow identify each type of action?
If I use the same basic code in the JTextField ActionEvent and JMenuItem ActionEvent, the JLabel updates correctly with the JTextField event but not JMenuItem event. They both use the messageField.setText property. Could the JMenuItem action be doing something to block the setText?
I can easily copy code in here, but it's pretty spaghetti-like at the moment, so if you want to see anything, let me know specifically and I'll post it.
I would appreciate any assistance that anyone would be able to provide.
---edit---
Wow!! Thanks for all of the comments and suggestions.
1 - I know it has to be my code. As I mentioned, I am really just cobbling stuff together from demos and tutorials, and trying to learn Java along the way. I've just never gotten the hang of object oriented....
2 - I do know the individual Listeners are working. I'm using System.out.println to validate, as well as inspecting those labels in debug mode to see they have indeed changed.
3 - I will look at the various links and code posted here and see if I can figure out what's wrong with my code.
Really, thanks again!
---edit---
Here is what I originally had in my createAndShowGUI method....
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Create XML for Photo Gallery");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CreateGalleryXML window = new CreateGalleryXML();
frame.setJMenuBar(window.createMenuBar());
frame.add(new CreateGalleryXML());
frame.pack();
frame.setVisible(true);
}
Seems like you yourself are doing something wrong, in your code. Without a proper SSCCE it's hard to say what thing you doing wrong, since it works perfectly, using same ActionListener for both JMenuItem and JTextField.
Here is a sample program to match with yours :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class UpdateLabel
{
private JLabel label;
private String labelText;
private ActionListener action = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
setLabelText((String) ae.getActionCommand());
label.setText(getLabelText());
}
};
private void setLabelText(String text)
{
labelText = text;
}
private String getLabelText()
{
return labelText;
}
private void createAndDisplayGUI()
{
final JFrame frame = new JFrame("Update Label");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(true);
JMenuBar menuBar = new JMenuBar();
JMenu programMenu = new JMenu("Program");
JMenuItem exitMenuItem = new JMenuItem("Exit");
exitMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
frame.dispose();
}
});
JMenu labelMenu = new JMenu("Label");
JMenuItem updateMenuItem = new JMenuItem("Update Label");
updateMenuItem.setActionCommand("Updated by JMenuItem");
updateMenuItem.addActionListener(action);
programMenu.add(exitMenuItem);
labelMenu.add(updateMenuItem);
menuBar.add(programMenu);
menuBar.add(labelMenu);
frame.setJMenuBar(menuBar);
JPanel contentPane = new JPanel();
label = new JLabel("I am the LABEL which will be updated!!");
contentPane.add(label);
JTextField tfield = new JTextField(10);
tfield.setActionCommand("Updated by JTextField");
tfield.addActionListener(action);
frame.add(contentPane, BorderLayout.CENTER);
frame.add(tfield, BorderLayout.PAGE_END);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new UpdateLabel().createAndDisplayGUI();
}
});
}
}
And here is the output in both the cases :
and
Do check out the main method, might be you had failed to put your code inside EDT - Event Dispatcher Thread, that can lead to such issues too. All updates on the Swing GUI, must be done on the Event Dispatcher Thread.
LATEST EDIT
It seems to me that CreateGalleryXML extends JPanel by the look of it. See at Line 3 of this below code taken from your update, here you are initializing a new Object of CreateGalleryXML inside, when you already had one Object window created at Line 1:
CreateGalleryXML window = new CreateGalleryXML();
frame.setJMenuBar(window.createMenuBar());
frame.add(new CreateGalleryXML());
So try to change the above thingy to this
CreateGalleryXML window = new CreateGalleryXML();
frame.setJMenuBar(window.createMenuBar());
frame.add(window);
and see what happens and Please do revert back again :-)
Use Action to encapsulate common functionality that must be shared by menus and related components. See this example that extends AbstractAction.
Pretty much everything you could need to know is in the Java tutorials. Down the bottom they have demo's on how to do both menu's and text fields. They include source code to look at as well.
There's not much more I can say that they don't say better, but in answer to your questions:
Both, you can have separate listener's on each component, or one that figures out what component is responsible for causing the action event. I would suggest you use separate ones for each thing.
Can't really say with out seeing the code, are you sure that the action on the JMenu is even firing? Does it print something to the console etc if you use System.out.println somewhere?