Calling non-local variable in ActionPerformed - java

I have a circle randomly painted with 3 different colors (BLUE, RED and GREEN) and 3 Buttons with this same colors(BLUE, RED and GREEN) and if the Circle is RED and I press the RED Button I need to show up in the Label YOU WON if you choose wrong color YOU LOSE. It's very simple but i can't call in the ActionPerformed the variable (that is the color to match with the button) from paintComponent. Sry for my language too.
Here is the CODE with 2 Classes:
PaintPanel.class
public class PaintPanel extends JPanel implements ActionListener {
int x = 200, y = 250;
private JButton b1 = new JButton("BLUE");
private JButton b2 = new JButton("RED");
private JButton b3 = new JButton("GREEN");
JLabel label = new JLabel("Choose the right Color");
JPanel subPanel = new JPanel();
private Color[] colors;
public PaintPanel() {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(440, 440));
add(label, BorderLayout.NORTH);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
subPanel.add(b1);
b1.setForeground(Color.BLUE);
subPanel.add(b2);
b2.setForeground(Color.RED);
subPanel.add(b3);
b3.setForeground(Color.GREEN);
add(subPanel, BorderLayout.SOUTH);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Color[] colors = new Color[3];
colors[0] = Color.BLUE;
colors[1] = Color.RED;
colors[2] = Color.GREEN;
Color c1 = colors[randInt(colors.length)];
g.setColor(c1);
/* this.colors.equals(c1); !!!! HERE I TRIED !!!*/
g.fillOval(x, y, 30, 30);
}
private int randInt(int length) {
// TODO Auto-generated method stub
Random rand = new Random();
int randomColor = rand.nextInt(length);
return randomColor;
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
if (Color.BLUE.equals(colors)) {
label.setText("You WIN");
}
}else {
label.setText("You LOSE");
}
if (e.getSource() == b2) {
}
if (e.getSource() == b3) {
}
}
}
Another one - DrawCircle.class -
public class DrawCircle extends JFrame {
private JPanel painted;
public DrawCircle() {
painted = new PaintPanel();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
setBounds(0, 0, 800, 540);
add(painted);
setVisible(true);
}
public static void main(String[] args) {
new DrawCircle();
}
}

Just a couple notes: You cannot access a non-static method from a static context. Consider Placing your DrawCircle() method in a separate class. Create an instance of that class and call DrawCircle() from that instance.
Regarding PaintPanel.class please note that paintComponent() is called very frequently, and is not just called on initialization. The Colors you generate need to be saved in a place accessible by actionPerformed(). Consider creating a Color tmp member in your class structure and reference your correct answer from there. In addition, you appear to be missing a call to UpdateUI(). This code is not perfect, but it works well. Personally, I'd find a different way to generate new colors apart from overriding paintComponent(), but if you need it there, this example should prove helpful. Comment below with improvements:
package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class PaintPanel extends JPanel implements ActionListener
{
int x = 200, y = 250;
private JButton b1 = new JButton("BLUE");
private JButton b2 = new JButton("RED");
private JButton b3 = new JButton("GREEN");
JLabel label = new JLabel("Choose the right Color");
JPanel subPanel = new JPanel();
private Color[] colors;
Color tmp = null;
public PaintPanel()
{
setLayout(new BorderLayout());
setPreferredSize(new Dimension(440, 440));
add(label, BorderLayout.NORTH);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
subPanel.add(b1);
b1.setForeground(Color.BLUE);
subPanel.add(b2);
b2.setForeground(Color.RED);
subPanel.add(b3);
b3.setForeground(Color.GREEN);
add(subPanel, BorderLayout.SOUTH);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
colors = new Color[3]; //Referencing Class member colors instead of local variable
colors[0] = Color.BLUE;
colors[1] = Color.RED;
colors[2] = Color.GREEN;
tmp = colors[randInt(colors.length)]; //Read into a class member instead of a local variable
g.setColor(tmp);
System.out.println("Paint Triggered. New Color is: " + tmp.toString()); //todo remove this debugging line
g.fillOval(x, y, 30, 30);
}
private int randInt(int length)
{
// TODO Auto-generated method stub
Random rand = new Random();
int randomColor = rand.nextInt(length);
return randomColor;
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == b1) {
if (Color.BLUE.equals(tmp)) {
label.setText("You WIN");
} else {
label.setText("You Loose");
}
} else if (e.getSource() == b2) {
if (Color.RED.equals(tmp)) {
label.setText("You WIN");
} else {
label.setText("You Loose");
}
} else if (e.getSource() == b3) {
if (Color.GREEN.equals(tmp)) {
label.setText("You WIN");
} else {
label.setText("You Loose");
}
}
updateUI(); //<---------------IMPORTANT To Sync What you see with each button press.
}
}

I think you've simply messed up your braces (and your indentation). Please use an auto-indent or auto-format tool in an IDE, it will locate these problems quickly.
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
if (Color.BLUE.equals(colors)) {
label.setText("You WIN");
}
// v Problem is this extra brace
}else {
label.setText("You LOSE");
}
Change to
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
if (Color.BLUE.equals(colors)) {
label.setText("You WIN");
}
else {
label.setText("You LOSE");
}
} else if( //...

Your colors array should not be created in the paintComponent() method. It should be declared as a PaintPanel instance variable, and should be created in the PaintPanel constructor.
Here is a possibility (you do not need a separate class; I added a main to PaintPanel):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class PaintPanel extends JPanel implements ActionListener {
int x = 200, y = 250;
private JButton b1 = new JButton("BLUE");
private JButton b2 = new JButton("RED");
private JButton b3 = new JButton("GREEN");
JLabel label = new JLabel("Choose the right Color");
JPanel subPanel = new JPanel();
private Color circleColor;
public PaintPanel() {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(440, 440));
add(label, BorderLayout.NORTH);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
subPanel.add(b1);
b1.setForeground(Color.BLUE);
subPanel.add(b2);
b2.setForeground(Color.RED);
subPanel.add(b3);
b3.setForeground(Color.GREEN);
add(subPanel, BorderLayout.SOUTH);
Random rand = new Random();
int rc = rand.nextInt(3);
switch (rc) {
case 1:
circleColor = Color.RED;
break;
case 2:
circleColor = Color.GREEN;
break;
default:
circleColor = Color.BLUE;
break;
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(circleColor);
g.fillOval(x, y, 30, 30);
}
#Override
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();
if (b.getForeground().equals(circleColor)) {
label.setText("You WIN");
} else {
label.setText("You LOSE");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// create the main frame
JFrame frame = new JFrame();
// create the component to display in the frame
PaintPanel comp = new PaintPanel();
frame.add(comp, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent arg0) {
System.exit(0);
}
});
}
});
}
}

Related

Trying To Delay the Appearance of JLabels in a JDialog

Hi I've there a little problem: What I want is to delay the appearance of JLabels in a JDialog-Window, in terms of that the first line of JLabels shoud come out and then two seconds later the second line of Jlabels etc.
I've tried something with Windowlistener,the doClick()-Method etc., bu every time the Jdialog revalidates all of its panels AT ONCE and shows them without any delaying!
Please help me(Just copy the code below and try out)!
package footballQuestioner;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
public class attempter {
public static void main(String[] args) throws InterruptedException {
JDialog dialog = new Punkte();
}
}
class Punkte extends JDialog {
private JPanel screenPanel = new JPanel(new GridLayout(4, 1));
private JButton button = new JButton();
private int i = 1;
private class WindowHandler implements WindowListener {
#Override
public void windowActivated(WindowEvent e) {
}
#Override
public void windowClosed(WindowEvent e) {
}
#Override
public void windowClosing(WindowEvent e) {
}
#Override
public void windowDeactivated(WindowEvent e) {
}
#Override
public void windowDeiconified(WindowEvent e) {
}
#Override
public void windowIconified(WindowEvent e) {
}
#Override
public void windowOpened(WindowEvent e) {
button.doClick(1000);
button.doClick(1000);
button.doClick(1000);
button.doClick(); // here im trying to delay the appearance of the
// JLabels....
}
}
private class ButtonHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
switch (i) {
case 1:
settingUpPanel(getPanelFromScreenPanel(i), "Right", new Color(
102, 205, 0));
settingUpPanel(getPanelFromScreenPanel(i), "Wrong", Color.RED);
break;
case 2:
settingUpPanel(getPanelFromScreenPanel(i), "Trefferquote",
Color.YELLOW);
break;
case 3:
settingUpPanel(getPanelFromScreenPanel(i), "Ausgezeichnet",
Color.BLUE);
break;
}
System.out.println(i);
i++;
}
}
public Punkte() {
button.addActionListener(new ButtonHandler());
addWindowListener(new WindowHandler());
setModal(true);
setResizable(true);
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
settingUpScreenPanel();
add(screenPanel);
setSize(1200, 1000);
centeringWindow();
setVisible(true);
}
private void settingUpScreenPanel() {
JPanel titlePanel = new JPanel(new GridBagLayout());
JPanel rightWrongCountPanel = new JPanel(new GridLayout(1, 2));
JPanel shareOfRightQuestions = new JPanel(new GridBagLayout());
JPanel grade = new JPanel(new GridBagLayout());
settingUpPanel(titlePanel, "Result", Color.BLACK);
// settingUpPanel(rightWrongCountPanel,
// "Right: "+numberOfRightAnsers+"/6",new Color(102,205,0));
// settingUpPanel(rightWrongCountPanel,
// "Wrong: "+(6-numberOfRightAnsers)+"/6", Color.RED);
// settingUpPanel(shareOfRightQuestions,
// "Trefferquote: "+(numberOfRightAnsers*100/6)+"%",Color.YELLOW);
// settingUpPanel(summaSummarum,
// getBufferedImage("footballQuestioner/Strich.png"));
// settingUpPanel(grade,"Aushezeichnet", Color.BLUE);
borderingJPanel(screenPanel, null, null);
titlePanel.setOpaque(false);
rightWrongCountPanel.setOpaque(false);
shareOfRightQuestions.setOpaque(false);
grade.setOpaque(false);
screenPanel.add(titlePanel);
screenPanel.add(rightWrongCountPanel);
screenPanel.add(shareOfRightQuestions);
screenPanel.add(grade);
}
private void settingUpPanel(JComponent panel, String string, Color color) {
Font font = new Font("Rockwell Extra Bold", Font.PLAIN, 65);
JPanel innerPanel = new JPanel(new GridBagLayout());
JLabel label = new JLabel(string);
label.setForeground(color);
label.setFont(font);
innerPanel.add(label);
innerPanel.setOpaque(false);
panel.add(innerPanel);
panel.validate();
panel.repaint();
}
public JPanel getPanelFromScreenPanel(int numberOfPanel) {
JPanel screenPanel = (JPanel) getContentPane().getComponent(0);
JPanel labelPanel = (JPanel) screenPanel.getComponent(numberOfPanel);
return labelPanel;
}
public void centeringWindow() {
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x;
int y;
x = (int) (dimension.getWidth() - getWidth()) / 2;
y = (int) (dimension.getHeight() - getHeight()) / 2;
setLocation(x, y);
}
public void borderingJPanel(JComponent panel, String jPanelname,
String fontStyle) {
Font font = new Font(fontStyle, Font.BOLD + Font.ITALIC, 12);
if (jPanelname != null) {
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory
.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY,
Color.WHITE), jPanelname,
TitledBorder.DEFAULT_JUSTIFICATION,
TitledBorder.DEFAULT_POSITION, font));
} else if (jPanelname == null || fontStyle == null) {
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory
.createEtchedBorder(EtchedBorder.LOWERED, Color.BLACK,
Color.WHITE)));
}
panel.setOpaque(false);
}
}
This is a really good use case for javax.swing.Timer...
This will allow you to schedule a callback, at a regular interval with which you can perform an action, safely on the UI.
private class WindowHandler extends WindowAdapter {
#Override
public void windowOpened(WindowEvent e) {
System.out.println("...");
Timer timer = new Timer(2000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JPanel panel = getPanelFromScreenPanel(1);
panel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int index = 0; index < 100; index++) {
panel.add(new JLabel(Integer.toString(index)), gbc);
}
panel.revalidate();
}
});
timer.start();
timer.setRepeats(false);
}
}
Now, if you wanted to do a series of actions, separated by the interval, you could use a counter to determine the number of "ticks" that have occurred and take appropriate action...
private class WindowHandler extends WindowAdapter {
#Override
public void windowOpened(WindowEvent e) {
System.out.println("...");
Timer timer = new Timer(2000, new ActionListener() {
private int counter = 0;
private int maxActions = 10;
#Override
public void actionPerformed(ActionEvent e) {
switch (counter) {
case 0:
// Action for case 0...
break;
case 1:
// Action for case 1...
break;
.
.
.
}
counter++;
if (counter >= maxActions) {
((Timer)e.getSource()).stop();
}
}
});
timer.start();
}
}
Take a look at How to use Swing Timers for more details

How can i display colors in a JComboBox?

The main idea is, that the Combo box should show colors in the selection area instead of the normal String.
This is the code i've made so far.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Colors extends JFrame implements ActionListener {
private JComboBox combo;
private JPanel panel;
private final Color[] content = {Color.red, Color.blue, Color.green, Color.black,
Color.yellow};
public Colors() {
super("Colors");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocation(500, 150);
setSize(250, 100);
setResizable(false);
Container c = getContentPane();
c.setLayout(new FlowLayout());
panel = new JPanel();
c.add(panel);
getCombo();
}
private void getCombo() {
combo = new JComboBox(content);
combo.setSelectedIndex(4);
combo.addActionListener(this);
panel.add(combo);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == combo) {
int choose = combo.getSelectedIndex();
if (choose == 0) {
panel.setBackground(content[0]);
} else if (choose == 1) {
panel.setBackground(content[1]);
} else if (choose == 2) {
panel.setBackground(content[2]);
} else if (choose == 3) {
panel.setBackground(content[3]);
} else if (choose == 4) {
panel.setBackground(content[4]);
} else if (choose == 5) {
panel.setBackground(content[5]);
}
}
}
public static void main(String[] args) {
Colors run = new Colors();
run.setVisible(true);
}
}
This just show awt reference and the GBR number, I want the colors to be shown in the Combo box

Can't change the color of my ovals

I for some reason, unknown to me, I cannot figure out how to change the color of the ovals. They stay black even though I have set them up to be red and blue. Thanks for any help.
ControlPanel class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.JFrame;
public class ControlPanel extends JPanel
{
private BallPanel ball1, ball2;
//declare all your components here
private JButton upR, downR, leftR, rightR, stopR, upB, downB, leftB, rightB, stopB;
private JSlider delayR, delayB;
private BallPanel redC, blueC;
private int DIAMETER = 30;
private JPanel redButtons, blueButtons, sliderR, sliderB, top, bottom, left, canvasCY;
private JLabel redDelay, blueDelay;
public ControlPanel(int width, int height)
{
width = 450;
height = 300;
//create 2 ball panels
redC = new BallPanel(0,10,Color.red,Color.cyan);
blueC = new BallPanel(0,10,Color.blue,Color.yellow);
//create 10 buttons
upR = new JButton("Up Red");
downR = new JButton("Down Red");
leftR = new JButton("Left Red");
rightR = new JButton("Right Red");
stopR = new JButton("Stop Red");
upB = new JButton("Up Blue");
downB = new JButton("Down Blue");
leftB = new JButton("Left Blue");
rightB = new JButton("Right Blue");
stopB = new JButton("Stop Blue");
//create 2 sliders
delayR=new JSlider(SwingConstants.VERTICAL,0,50,25);
delayB=new JSlider(SwingConstants.VERTICAL,0,50,25);
//add the corresponding listener to sliders and buttons
upR.addActionListener(new ButtonListener());
downR.addActionListener(new ButtonListener());
leftR.addActionListener(new ButtonListener());
rightR.addActionListener(new ButtonListener());
stopR.addActionListener(new ButtonListener());
upB.addActionListener(new ButtonListener());
downB.addActionListener(new ButtonListener());
leftB.addActionListener(new ButtonListener());
rightB.addActionListener(new ButtonListener());
stopB.addActionListener(new ButtonListener());
//organize 5 buttons into a panel using grid layout
redButtons= new JPanel(new GridLayout(5,1));
redButtons.add(upR);
redButtons.add(downR);
redButtons.add(leftR);
redButtons.add(rightR);
redButtons.add(stopR);
//organize 5 buttons into a panel using grid layout
blueButtons= new JPanel(new GridLayout(5,1));
blueButtons.add(upB);
blueButtons.add(downB);
blueButtons.add(leftB);
blueButtons.add(rightB);
blueButtons.add(stopB);
//create 2 labels
redDelay = new JLabel("Red Ball Delay");
blueDelay = new JLabel("Blue Ball Delay");
//organize a label and a slider into a panel using border layout
sliderR = new JPanel(new BorderLayout());
sliderR.add(redDelay, BorderLayout.NORTH);
sliderR.add(delayR, BorderLayout.SOUTH);
//organize the panel containing buttons and the panel with a slider
top = new JPanel(new GridLayout(1,2));
top.add(redButtons);
top.add(sliderR);
//organize a label and a slider into a panel using border layout
sliderB = new JPanel(new BorderLayout());
sliderB.add(blueDelay, BorderLayout.NORTH);
sliderB.add(delayB, BorderLayout.SOUTH);
//organize the panel containing buttons and the panel with a slider
bottom = new JPanel(new GridLayout(1,2));
bottom.add(blueButtons);
bottom.add(sliderB);
left=new JPanel(new GridLayout(2,1));
left.add(top);
left.add(bottom);
canvasCY = new JPanel(new GridLayout(2,1));
canvasCY.add(redC);
canvasCY.add(blueC);
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, canvasCY);
setLayout(new GridLayout(0,1));
add(sp);
sp.setVisible(true);
}
//The ButtonListener class defines actions to be taken in case
//each of 10 buttons are pushed.
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
Object action = event.getSource();
//if the up button for the red ball is pushed.
if (event.getSource() == upR)
redC.up();
else if (event.getSource() == downR)
redC.down();
else if (event.getSource() == leftR)
redC.left();
else if (event.getSource() == rightR)
redC.right();
else if (event.getSource() == stopR)
redC.suspend();
if (event.getSource() == upB)
blueC.up();
else if (event.getSource() == downB)
blueC.down();
else if (event.getSource() == leftB)
blueC.left();
else if (event.getSource() == rightB)
blueC.right();
else if (event.getSource() == stopB)
blueC.suspend();
}
} //end of ButtonListener
//The SliderListener defines actions to be taken in case
//each of the 2 sliders is moved by a user
private class SliderListener implements ChangeListener
{
public void stateChanged(ChangeEvent event)
{
}
} //end of SliderListener
}
BallPanel class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Color;
import java.awt.Graphics;
public class BallPanel extends JPanel
{
int x;
int y;
Color ballColor;
Color backColor;
Timer timer;
int delay;
int stepX=3;
int stepY=0;
final int CIRCLE_DIAMETER = 20;
public BallPanel(int x, int y, Color ballColor, Color backColor)
{
this.x=x;
this.y=y;
this.ballColor=ballColor;
this.backColor=backColor;
delay=20;
stepX=3;
stepY=0;
timer= new Timer(delay, new MovingBallListener());
timer.start();
repaint();
}
public void up()
{
stepX=0;
stepY=-3;
repaint();
}
public void down()
{
stepX=0;
stepY=3;
repaint();
}
public void left()
{
stepX=-3;
stepY=0;
repaint();
}
public void right()
{
stepX=3;
stepY=0;
repaint();
}
public void suspend()
{
stepX=0;
stepY=0;
repaint();
}
public void setDelay(int delayNum)
{
timer.setDelay(delayNum);
}
public void paintComponent(Graphics page)
{
super.paintComponent(page);
page.fillOval(x,y,CIRCLE_DIAMETER,CIRCLE_DIAMETER);
page.setColor(ballColor);
setBackground(backColor);
}
private class MovingBallListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (x > getSize().getWidth()-CIRCLE_DIAMETER && stepY == 0)
stepX=-3;
stepY=0;
repaint();
if(x < getSize().getWidth()-CIRCLE_DIAMETER && stepY == 0)
stepX=3;
stepY=0;
repaint();
}
}
}
hw12.html
Assignment 12 Applet
I believe it has to do with this in javadocs for setColor
"Sets this graphics context's current color to the specified color. All subsequent graphics operations using this graphics context use this specified color."
So flip this
page.fillOval(x,y,CIRCLE_DIAMETER,CIRCLE_DIAMETER);
page.setColor(ballColor);
to be
page.setColor(ballColor);
page.fillOval(x,y,CIRCLE_DIAMETER,CIRCLE_DIAMETER);
so that you are drawing with ballColor

Issues with ActionListener(Java) [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Issues with ActionListener (Java)
I am trying to implement action listener on two buttons in JFrame, but the issue is one of the two button is performing both the functions; but i've not configured it to do so.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class MyChangingCirlce implements ActionListener {
JButton colorButton, labelButton;
JLabel myLabel;
MyDrawPanel mdp;
JFrame frame;
public static void main(String[] args) {
MyChangingCirlce mcc = new MyChangingCirlce();
mcc.createFrame();
} // end of main
public void createFrame() {
frame = new JFrame();
colorButton = new JButton("Changing Colors");
labelButton = new JButton("Change Label");
myLabel = new JLabel("I'm a label");
mdp = new MyDrawPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(BorderLayout.CENTER, mdp);
frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
frame.getContentPane().add(BorderLayout.EAST, labelButton);
frame.getContentPane().add(BorderLayout.WEST, myLabel);
colorButton.addActionListener(this);
labelButton.addActionListener(this);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == colorButton) {
frame.repaint();
} else {
myLabel.setText("That's it");
}
}
}
My labelButton is performing both the action only 1 time; i.e it changes the color of the circle along with the label text.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyDrawPanel extends JPanel{
public void paintComponent(Graphics g)
{
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue= (int) (Math.random() * 255);
Color randomColor = new Color(red,green,blue);
g.setColor(randomColor);
g.fillOval(20,70,100,100);
}
}
You override colorButton and labelButton. So the 'else' is always kicking in. Changing the label will cause a redraw.
change
JButton colorButton = new JButton("Changing Colors");
JButton labelButton = new JButton("Change Label");
to
colorButton = new JButton("Changing Colors");
labelButton = new JButton("Change Label");
After writing myself a class to test it, I came about with this:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.Date;
public class Foo implements ActionListener {
JButton colorButton, labelButton;
JLabel myLabel;
JFrame frame;
MyDrawPanel mdp;
public static void main(String[] args) {
Foo mcc = new Foo();
mcc.createFrame();
} //end of main
public void createFrame() {
frame = new JFrame();
colorButton = new JButton("Changing Colors");
labelButton = new JButton("Change Label");
myLabel = new JLabel("I'm a label");
mdp = new MyDrawPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JSplitPane jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
mdp.setPreferredSize(new Dimension(150, 150));
jsp.setLeftComponent(mdp);
frame.setBounds(10, 10, 600, 600);
JPanel right = new JPanel();
right.add(BorderLayout.SOUTH, colorButton);
right.add(BorderLayout.EAST, labelButton);
right.add(BorderLayout.WEST, myLabel);
jsp.setRightComponent(right);
frame.getContentPane().add(jsp);
colorButton.addActionListener(this);
labelButton.addActionListener(this);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == colorButton) {
myLabel.setText("Color button's it");
frame.repaint();
} else {
myLabel.setText("That's it" + new Date().toString());
}
}
public class MyDrawPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color randomColor = new Color(red, green, blue);
g.setColor(randomColor);
g.fillOval(20, 70, 100, 100);
}
}
}

Java Swing: Enabling/Disabling all components in JPanel

I have a JPanel which contains a JToolbar (including few buttons without text) and a JTable and I need to enable/disable (make internal widgets not clickable). I tried this:
JPanel panel = ....;
for (Component c : panel.getComponents()) c.setEnabled(enabled);
but it doesn't work. Is there a better and more generic solution to enable/disable all internal components in a JPanel?
I have partially solved my problem using JLayer starting from the example here http://docs.oracle.com/javase/tutorial/uiswing/misc/jlayer.html:
layer = new JLayer<JComponent>(myPanel, new BlurLayerUI(false));
.....
((BlurLayerUI)layer.getUI()).blur(...); // switch blur on/off
class BlurLayerUI extends LayerUI<JComponent> {
private BufferedImage mOffscreenImage;
private BufferedImageOp mOperation;
private boolean blur;
public BlurLayerUI(boolean blur) {
this.blur = blur;
float ninth = 1.0f / 9.0f;
float[] blurKernel = {
ninth, ninth, ninth,
ninth, ninth, ninth,
ninth, ninth, ninth
};
mOperation = new ConvolveOp(
new Kernel(3, 3, blurKernel),
ConvolveOp.EDGE_NO_OP, null);
}
public void blur(boolean blur) {
this.blur=blur;
firePropertyChange("blur", 0, 1);
}
#Override
public void paint (Graphics g, JComponent c) {
if (!blur) {
super.paint (g, c);
return;
}
int w = c.getWidth();
int h = c.getHeight();
if (w == 0 || h == 0) {
return;
}
// Only create the offscreen image if the one we have
// is the wrong size.
if (mOffscreenImage == null ||
mOffscreenImage.getWidth() != w ||
mOffscreenImage.getHeight() != h) {
mOffscreenImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
}
Graphics2D ig2 = mOffscreenImage.createGraphics();
ig2.setClip(g.getClip());
super.paint(ig2, c);
ig2.dispose();
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(mOffscreenImage, mOperation, 0, 0);
}
#Override
public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) {
if ("blur".equals(pce.getPropertyName())) {
l.repaint();
}
}
}
I still have 2 problems:
In the link above events are relative to mouse only. How can I manage the keyboard events?
How can I create a "gray out" effect in place of blur?
It requires a recursive call.
import java.awt.*;
import javax.swing.*;
public class DisableAllInContainer {
public void enableComponents(Container container, boolean enable) {
Component[] components = container.getComponents();
for (Component component : components) {
component.setEnabled(enable);
if (component instanceof Container) {
enableComponents((Container)component, enable);
}
}
}
DisableAllInContainer() {
JPanel gui = new JPanel(new BorderLayout());
final JPanel container = new JPanel(new BorderLayout());
gui.add(container, BorderLayout.CENTER);
JToolBar tb = new JToolBar();
container.add(tb, BorderLayout.NORTH);
for (int ii=0; ii<3; ii++) {
tb.add(new JButton("Button"));
}
JTree tree = new JTree();
tree.setVisibleRowCount(6);
container.add(new JScrollPane(tree), BorderLayout.WEST);
container.add(new JTextArea(5,20), BorderLayout.CENTER);
final JCheckBox enable = new JCheckBox("Enable", true);
enable.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
enableComponents(container, enable.isSelected());
}
});
gui.add(enable, BorderLayout.SOUTH);
JOptionPane.showMessageDialog(null, gui);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
new DisableAllInContainer();
}
});
}}
I used the following function:
void setPanelEnabled(JPanel panel, Boolean isEnabled) {
panel.setEnabled(isEnabled);
Component[] components = panel.getComponents();
for(int i = 0; i < components.length; i++) {
if(components[i].getClass().getName() == "javax.swing.JPanel") {
setPanelEnabled((JPanel) components[i], isEnabled);
}
components[i].setEnabled(isEnabled);
}
}
you can overlay whole Container / JComponent
GlassPane block by default MouseEvents, but not Keyboard, required consume all keyevents from ToolKit
JLayer (Java7) based on JXLayer (Java6)
can't see reason(s) why not works for you
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class AddComponentsAtRuntime {
private JFrame f;
private JPanel panel;
private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;
public AddComponentsAtRuntime() {
JButton b = new JButton();
//b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 20));
panel = new JPanel(new GridLayout(0, 1));
panel.add(b);
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(panel, "Center");
f.add(getCheckBoxPanel(), "South");
f.setLocation(200, 200);
f.pack();
f.setVisible(true);
}
private JPanel getCheckBoxPanel() {
checkValidate = new JCheckBox("validate");
checkValidate.setSelected(false);
checkReValidate = new JCheckBox("revalidate");
checkReValidate.setSelected(true);
checkRepaint = new JCheckBox("repaint");
checkRepaint.setSelected(true);
checkPack = new JCheckBox("pack");
checkPack.setSelected(true);
JButton addComp = new JButton("Add New One");
addComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JButton b = new JButton();
//b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(400, 10));
panel.add(b);
makeChange();
System.out.println(" Components Count after Adds :" + panel.getComponentCount());
}
});
JButton removeComp = new JButton("Remove One");
removeComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int count = panel.getComponentCount();
if (count > 0) {
panel.remove(0);
}
makeChange();
System.out.println(" Components Count after Removes :" + panel.getComponentCount());
}
});
JButton disabledComp = new JButton("Disabled All");
disabledComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Component c : panel.getComponents()) {
c.setEnabled(false);
}
}
});
JButton enabledComp = new JButton("Enabled All");
enabledComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Component c : panel.getComponents()) {
c.setEnabled(true);
}
}
});
JPanel panel2 = new JPanel();
panel2.add(checkValidate);
panel2.add(checkReValidate);
panel2.add(checkRepaint);
panel2.add(checkPack);
panel2.add(addComp);
panel2.add(removeComp);
panel2.add(disabledComp);
panel2.add(enabledComp);
return panel2;
}
private void makeChange() {
if (checkValidate.isSelected()) {
panel.validate();
}
if (checkReValidate.isSelected()) {
panel.revalidate();
}
if (checkRepaint.isSelected()) {
panel.repaint();
}
if (checkPack.isSelected()) {
f.pack();
}
}
public static void main(String[] args) {
AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
}
}
#Kesavamoorthi
if you want to make it more general:
void setPanelEnabled(java.awt.Container cont, Boolean isEnabled) {
cont.setEnabled(isEnabled);
java.awt.Component[] components = cont.getComponents();
for (int i = 0; i < components.length; i++) {
if (components[i] instanceof java.awt.Container) {
setPanelEnabled((java.awt.Container) components[i], isEnabled);
}
components[i].setEnabled(isEnabled);
}
}

Categories

Resources