"Linking" JComponents in Java? - java

I have a few buttons and a few panels. Each button corresponds to a panel. I want to add an ActionListener to each button so that when the buttons are clicked, the visibility of the panels are toggled. However, inside the ActionPerformed method, I cannot get the JPanel. Here's basically what I have:
JFrame frame1=new JFrame();
JPanel panel=new JPanel();
frame1.add(panel);
JFrame frame2=new JFrame();
JButton btn=new JButton(panel.getName());
btn.addActionListener(new ActionListener(){
public void ActionPerformed(ActionEvent e){
(somehow get panel).setVisible(false);
}
});
frame2.add(btn);

It might be better to create a class that implements ActionListener. You could then pass in a reference to the parent JPanel and then refer to that in the actionPerformed method.
But if you really wanted to, you could use this convoluted one-liner.
((JComponent)e.getSource()).getParent().setVisible(false);

An AbstractAction could work well:
class ButtonAction extends AbstractAction {
private JPanel panel;
public ButtonAction(JPanel panel) {
super(panel.getName());
this.panel = panel;
}
public void actionPerformed(ActionEvent e) {
panel.setVisible(false);
}
}
elsewhere:
someContainer.add(new JButton(new ButtonAction(panel)));

It is not very good solution, but you can link swing components in following way
button.putClientProperty("panel", panel1);
//and somewhere in code
((JPanel)button.getClientProperty("panel")).setVisible(false);

This should work:
e.getSource().getParent().setVisible(false);

Related

Adding JLabels to JFrame using ActionListener and for loop

I want to add a JLabels to JFrame with for loop and ActionListener. The idea is: I have a button, and when i click the button, program is adding labels, but in my code when i click button nothing happens, without button and ActionListener, labels are adding properly. Code:
public class Test extends JFrame implements ActionListener{
JLabel[] labels;
TextField dane;
JButton button;
public Test(){
super();
dane=new TextField();
button=new JButton("Oblicz");
setLayout(new GridLayout(33,0));
add(dane);
add(button);
setVisible(true);
pack();
}
#Override
public void actionPerformed(ActionEvent v) {
showGUI();
revalidate();
repaint();
}
private JLabel[] createLabels(){
JLabel[] labels=new JLabel[20];
for (int i=0;i<20;i++){
labels[i]=new JLabel("message"+i);
}
return labels;
}
private void showGUI(){
labels=createLabels();
for (int i=0;i<labels.length;i++){
this.add(labels[i]);
}
}
public static void main(String[] args){
new Test();
}
}
Ok, i changed my code as you sugested, but it still doesn't work. What's wrong here ? I have no idea( I'm very beginner so every suggestions would be nice )
...but in my code when i click button nothing happens
I don't see where you've attached a listener to your button. Try:
button.addActionListener(this);
When adding components to a visible GUI the basic code is:
panel.add(...);
panel.revalidate(); // to invoke the layout managers
panel.repaint(); // to paint the new components
So after the loop is finished adding the labels to the frame you need to revalidate() the frame.

How to access a JFrame from anonymous ActionListener for adding a panel in frame?

I want to add a JPanel in a frame if a certain button is clicked and I don't know how to manage that from an anonymous ActionListener. Here is the code:
public class MyFrame extends JFrame {
JPanel panel;
JButton button;
public MyFrame() {
button = new JButton("Add panel");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
panel = new JPanel();
//here I want to add the panel to frame: this.add(panel), but I don't know
//how to write that. In these case "this" refers to ActionListener, not to
//frame, so I want to know what to write instead of "this" in order to
//refer to the frame
}
}
this.add(button);
}
Thank you in advance!
here I want to add the panel to frame: this.add(panel), but I don't
know how to write that. In these case "this" refers to ActionListener,
not to frame, so I want to know what to write instead of "this" in
order to refer to the frame
Instead of this.add(...) just use add(..) or you can use MyFrame.this.add(..) cause using this in anonymous class means that you are referring to ActionListener instance.
Actually you may also have to call revalidate() and repaint() after you add a component.
User generic code in your ActionListener so you don't need to hardcode the class that you are using.
Something like:
JButton button = (JButton)event.getSource();
Window window = SwingUtilities.windowForCompnent( button );
window.add(...);
public class MyFrame extends JFrame {
JPanel panel;
JButton button;
public MyFrame() {
button = new JButton("Add panel");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
panel = new JPanel();
//here I want to add the panel to frame: this.add(panel), but I don't know
//how to write that. In these case "this" refers to ActionListener, not to
//frame, so I want to know what to write instead of "this" in order to
//refer to the frame
MyFrame.this.add(panel);
}
}
this.add(button);
}

How to make a class a component in Java Swing?

I am a beginner in Java programming so I do not know if I may be using the correct terms here. Basically, I have an assignment to program a little applet that changes the color of the background to whatever of the 4 color buttons is pressed. I was given a sample code with ActionListener and was told to use MouseListener to implement it.
I was able to successfully program it to work and then the requirements changed. Below is my current code that works (before the requirements changed).
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class ButtonPanel extends JPanel implements MouseListener{
private JButton abutton, bbutton, cbutton, dbutton;
public ButtonPanel(){
abutton = new JButton("Cyan");
bbutton = new JButton("Orange");
cbutton = new JButton("Magenta");
dbutton = new JButton("Yellow");
add(abutton);
add(bbutton);
add(cbutton);
add(dbutton);
/* register the specific event handler into each button */
abutton.addMouseListener(this);
bbutton.addMouseListener(this);
cbutton.addMouseListener(this);
dbutton.addMouseListener(this);
}
/* implementation for the Mouse Event */
public void mouseClicked(MouseEvent evt){
Object source = evt.getSource();
if (source == abutton) setBackground(Color.cyan);
else if (source == bbutton) setBackground(Color.orange);
else if (source == cbutton) setBackground(Color.magenta);
else if (source == dbutton) setBackground(Color.yellow);
repaint();
}
public void mousePressed(MouseEvent evt){
}
public void mouseEntered(MouseEvent evt){
}
public void mouseReleased(MouseEvent evt){
}
public void mouseExited(MouseEvent evt){
}
}
class ButtonFrame extends JFrame{
public ButtonFrame(){
setTitle("Low-level Mouse Event to Set Color");
setSize(50, 50);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){ System.exit(0);}
});
Container contentPane = getContentPane();
contentPane.add(new ButtonPanel());
}
}
public class ME_SetColor {
public static void main(String[] args) {
JFrame frame = new ButtonFrame();
frame.pack();
frame.setSize(400, 250);
frame.setVisible(true);
}
}
The new requirement is to exclude extends JPanel and any other extensions for class ButtonPanel. So the modified class has to be
class ButtonPanel implements MouseListener{
private JButton abutton, bbutton, cbutton, dbutton;
Without JPanel, the ButtonPanel class would not be a component and therefore it can not be added to contentPane. Is there another way to make this ButtonPanel a component so it can be added to contentPane? Or is there any other ways to implement this program?
Without JPanel, the ButtonPanel class would not be a component
You could extend JComponent. JComponent is the base class for Swing components. JPanel itself is a simple extension of JComponent (with one minor difference: a JPanel's opaque property is true by default, whereas it's false by default for JComponent).
But if your requirement is to exclude any extensions for ButtonPanel, you're right, you can't actually make it a component that can be added to a container.
However, you could include a component as a field of ButtonPanel:
class ButtonPanel implements ... {
private JPanel panel;
private JButton abutton, bbutton, cbutton, dbutton;
...
public JPanel getPanel() { return panel; }
}
Then in ButtonFrame:
add(new ButtonPanel().getPanel());
You don't need to call getContentPane() and contentPane.add by the way, as a frame's own add methods automatically do this.

Java actionlistener doesn't work

I just started learning Java 1 week ago, and I'm a 100% totally beginner. In this code, I can't seem to be able to put an actionlistener/get one to work. I don't even know where/how/in what way to put it, despite reading dozens of tutorials. I've created a JFrame with a JPanel in it, and on the JPanel there's a button. So far so good (and working). But then, I want it to be so that if the button is clicked, another button appears. Thank you sooo much in advance!
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class Skeleton extends JFrame implements ActionListener {
public static void main(String[] args) {
//------------------------------------------------
JFrame frame = new JFrame("Skeleton");
JPanel panel = new JPanel();
frame.setContentPane(panel);
frame.setSize(600,600);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
JButton button = new JButton("This is a button.");
JButton button2 = new JButton("Hello");
panel.setLayout(null);
button.setBounds(20,20,200,25);
button2.setBounds(20,70,200,25);
panel.add(button);
//-------------------------------------------
button.addMouseListener(this);
}
public void ActionPerformed(ActionEvent e) {
System.out.println("Hello");
}
}
i will give you some advice
1) Don't implement ActionListener in top classes, use anonymous classes or private classes instead.
Example :
Anonymous class (also call Swing Actions)
myComponent.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent evt){
//code here
}
})
or
//inner class
public class Skeleton{
// in some part
private class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent evt){
//code here
}
}
}
2) Your code won't compile cause you are not implementing ActionListener interface
public void actionPerformed(ActionEvent evt) is the signature.
You have to addActionListener to your component
button.addActionListener(this);
3) Don't use null layout, cause you'll have a lot of problem if you want to add more components or resize windows cause you have to setBounds manually and it will be frustrating instead use [Layout Manager][1].
4) Try to not extends JFrame if is not necesary instead have a reference in your class, for example.
public class Skeleton{
private JFrame frame;
}
You need to add the actionlistener.
Register an instance of the event handler class as a listener on one or more components. For example:
yourdesiredcomponent.addActionListener(this);
For more details check the doc

Java GUI panel unable to refresh?

I have 3 panels in the frame, panel, panel1, panel2. When I click on the button it doesn't remove the panel from the frame.
private class ButtonListener implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
// some stuffs here.
++current;
frame.remove(panel1);
frame.revalidate();
frame.repaint();
}
}
edit: i used this too but it doesn't work as well
frame.remove(panel1);
frame.getContentPane().invalidate();
frame.getContentPane().validate();
frame.getContentPane().repaint();

Categories

Resources