Component passed to constructor doesn't display - java

I've created a class that creates a panel, and in the constructor I'm passing a button with an action listener attached.
This is the code for the button:
JButton back = new JButton("Back");
back.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
menus.show(contentPane, "Main");
}
});
It's then passed to a constructor like so:
lightsPane = new lightsPane(back).contents;
tasksPane = new Tasks(tasksBack).contents;
tvPane = new TV(tvBack).contents;
Inside the classes the button is added to a JPanel and that JPanel is then added to contents. Like so:
public class lightsPane{
JPanel contents;
lightsPane(JButton back){
contents = new JPanel(new BorderLayout);
//add back button to lower right of panel
JPanel backPane = new JPanel();
backPane.setLayout(new BorderLayout());
backPane.add(back, BorderLayout.CENTER);
contents.add(backPane, BorderLayout.SOUTH);
}
}
I know the constructor is working right as when I create a button inside it to add to contents it displays fine. What's going on here? Can I pass this button to the constructor or not? If I can why isn't this displaying?

yes, you can pass a button to a constructor as you are passing a reference which you used in another class it is perfectly fine.

There is nothing wrong with passing the JButton through the constructor if it is used properly. The class either is not using it at all or is using it but in the wonge way.

Related

GUI won't open when button pressed (Java)

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);
}
}

Java method being called, but elements not displaying in GUI

I have the following Java method, which I am trying to use to add some buttons to a GUI:
private void addButtons(){
JButton addBtn = new JButton("Add");
JButton saveBtn = new JButton("Save");
addBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
/*Code to be added here */
}
});
addBtn.setBounds(1150, 135, 30, 15);
saveBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
/*Code to be added here */
}
});
saveBtn.setBounds(1190, 135, 30, 15);
System.out.println("'addButtons()' method is being called");
}
I am calling this method from a private void initialize() method in the same class. I know that initialize() is being called because all of the other method calls that it performs are happening, and displaying in the GUI.
However, for some reason, the buttons that I am trying to create and add to my GUI with this method are not being displayed...
Can anyone point out to me why this is, and what I'm doing wrong?
Edit
Apologies- I'm calling the method in a private void initialize() method in the same class:
private void initialize(){
...
(other code that is successfully adding stuff to the GUI)
...
addButtons();
}
I am seeing the System.out.println() message from the end of the addButtons() method in the console when I click the button that calls the initialize() method... and all of the other code from the `initialize()' method is being called (for example, it's opening a new window, and adding some text, textboxes and tables to the window)...
Edit 26/06/2014 # 09:15
The class where I have written this code extends JPanel:
public class JConfigurationPane extends JPanel implements UndoableEditListener, ChangeListener
I am now no longer using the addButtons() method that I had previously mentioned, and am trying to use my initialize() method to add the buttons to the JPanel:
public void initialize(){
// Code that initialises other elements in the GUI, such as Jlabels, layout, etc
JButton addBtn = new JButton("Add");
JButton saveBtn = new JButton("Save");
this.add(addBtn);
this.add(saveBtn);
}
But the buttons still don't appear when I run the application, even though all of the other graphical elements in the initialize() method do... Any ideas why this is? I've added some debug before and after where I create the buttons, and where I add them to the GUI- the debug is displayed in the console, so the code to create and add the buttons must be called...
Where are you adding these buttons to the form?
You are creating buttons in the method yes, and attaching listeners to these but the buttons themselves aren't being added to the form which is why you cant see them.
e.g you should be doing something like:
yourForm.add(addBtn);
yourForm.add(saveBtn);
or add these to a JPanel or something - finally making sure you add this JPanel
I managed to solve this by moving the code from my addButtons() method to my initialize() method, and setting the bounds of each button immediately after creating it:
JButton addBtn = new JButton("Add");
addBtn.setBounds(1000, 135, 75, 25);

Difference between creating an object within the constructor vs outside of the constructor?

Within my program, I am trying to create a toolbar within a frame. Within the toolbar, I have three buttons that are represented with a picture instead of text.
The problem is that I have found that there is a difference in how the buttons are displayed if I create the JButton objects within the constructor, compared to if I did this outside of the constructor (but still within the JFrame class).
My code when I create the buttons within the constructor :
public class Tool extends JFrame
{
public Tool()
{
JToolbar bar = new JToolBar();
JButton button1 = new JButton(img1);
JButton button2 = new JButton(img2);
JButton button3 = new JButton(img3);
bar.add(button1);
bar.add(button2);
bar.add(button3);
}
}
Then the buttons are added nicely and neatly to the toolbar.
However, if I do this:
public class Tool extends JFrame
{
JButton button1 = new JButton(img1);
JButton button2 = new JButton(img2);
JButton button3 = new JButton(img3);
public Tool()
{
JToolbar bar = new JToolBar();
bar.add(button1);
bar.add(button2);
bar.add(button3);
}
}
Then, the buttons are still added to the toolbar. BUT instead of being formatted nicely, they seem to have a border around them (similar to if you just copied an image off of google and paste it onto a powerpoint presentation, for example, and you get a square border around the image).
Why is this the case? Why does it matter where I create the JButton objects?
Thank you in advance.
Edit (complete CORRECT code):
In the code below, button1 and button2 are created within the constructor, whereas button3 is created outside of the constructor. As you can see, there is a faint white border around the button with the text "Java", compared to the two other buttons.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Tool extends JFrame
{
JButton button3 = new JButton("Java");
public Tool()
{
super("Tool");
setLookAndFeel();
setSize(370, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button1 = new JButton("Help");
JButton button2 = new JButton("SOS");
//build toolbar
JToolBar bar = new JToolBar();
bar.add(button1);
bar.add(button2);
bar.add(button3);
// build text area
JTextArea edit = new JTextArea(8, 40);
JScrollPane scroll = new JScrollPane(edit);
// create frame
BorderLayout border = new BorderLayout();
setLayout(border);
add("North", bar);
add("Center", scroll);
setVisible(true);
}
private void setLookAndFeel()
{
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
}
catch(Exception e)
{
}
}
public static void main(String[] arguments)
{
Tool loot = new Tool();
}
}
In the first case, you just have three local variables declared in the constructor.
In the second case, your Tool class has three fields. You can then refer to those fields in other methods, and they are part of the state of the object.
That's a significant difference in itself, but shouldn't affect the behaviour in itself. However, it also affects the timing of when the JButton instances are created - when they're fields, the initializer is being executed before you call setLookAndFeel and before you call setSize.
After experimenting a bit, it seems that it's the look and feel which is important here. I suggest you change your code to make setLookAndFeel a static method, and then call that from main before you create any GUI components. You'll then get a consistent experience. (I would suggest only catching UnsupportedLookAndFeelException and ReflectiveOperationException, and at least logging any exception, instead of just continuing without any trace of what's wrong, too...)

Java Swing: Access panel components from another class

Hi i basically have two classes,
one main and one just to separate the panels, just for code readability really.
i have :
public class Main{
public static void main (String args[]) {
JFrame mainJFrame;
mainJFrame = new JFrame();
//some other code here
CenterPanel centerPanel = new CenterPanel();
centerPanel.renderPanel();
mainFrame.add(centerPanel.getGUI());
}
}
class CenterPanel{
JPanel center = new JPanel();
public void renderPanel(){
JButton enterButton = new JButton("enter");
JButton exitButton = new JButton("exit");
center.add(exitButton);
center.add(enterButton);
}
public JComponent getGUI(){
return center;
}
}
Above code works perfectly. It renders the centerPanel which contains the buttons enter and exit. My question is:
I still need to manipulate the buttons in the main, like change color, add some action listener and the likes. But i cannot access them anymore in the main because technically they are from a different class, and therefore in the main, centerPanel is another object.
How do I access the buttons and use it (sets, actionlisteners, etc)? even if they came from another class and i still wish to use it inside the main?Many Thanks!
Make the buttons members of CenterPanel
class CenterPanel{
JPanel center = new JPanel();
JButton enterButton;
JButton exitButton;
public void renderPanel(){
enterButton = new JButton("enter");
exitButton = new JButton("exit");
center.add(exitButton);
center.add(enterButton);
}
public JButton getEnterButton()
{
return enterButton;
}
public JButton getExitButton()
{
return exitButton;
}
public JComponent getGUI(){
return center;
}
}
You have reference to centerPanel in your main method. After you invoke centerPanel.renderPanel();
the buttons will be added to the 'center' reference of type JPanel in CenterPanel instance. You can get the reference of 'center' by invoking centerPanel.getGUI(); in main method.This will return the center reference of type JComponent. JComponent is a awt container.so, you can call center.getComponents(). This will return all the components in an array present in the JPanel. i.e. center reference. You can iterate them, get their type and do whatever you want.

Change JButtons Names and use the new Name. in methods

I have a swing java application on which I have a 114 button
I have created the buttons by a loop
Container pane = getContentPane();
JPanel panel = new JPanel();
JButton b;
for(int i=1;i<115;i++)
{
b = new JButton(""+i);
panel.add(b);
}
So all buttons will take the name b !!!
that is the problem here
I want to give each button a different name to execute different action for each button.
by ActionListener class
JButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
}
});
No, your buttons don't have the name b. You are using a local variable b inside the for loop. You can for instance create an array of buttons and store your JButton instances there. Later, you can loop through that array to change the buttons text.
Perhaps you could add your buttons to a Map using what you want to call the button as the key. Then you can access the button by calling the get() on the Map with whatever you want to call the button.

Categories