One button will make new file in the source, the second button will write what is in the text field on my JFrame inside that file, third button will do the exact opposite (write from that file to the text field), fourth button will delete text from the file, but not the file as a whole, fifth button will close the project window and the sixth one will delete the file. I need also that the layout around buttons needs to be colored and I would like if the project will tell me if the file was created/deleted too. I hope you can help me with that. I'm trying this all day but something still doesn't work. If I make some progress, I will comment here.
Edit:
For now I have this, but it doesn't show anything:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class project2 {
public static void main(String[] args) {
JFrame window = new JFrame("New window");
JButton button = new JButton ("Create");
JButton writeto = new JButton ("Write to file");
JButton close = new JButton ("Close");
JButton delete = new JButton ("Delete file");
JTextField field = new JTextField();
JLabel text = new JLabel("Testing");
JButton writefrom = new JButton("Write from file");
JButton deletetext = new JButton("Delete");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(550,450);
window.setVisible(true);
}
}
I did it somehow. I think I just didn't know how to make the buttons to appear, but after I found some functional parts of code on the internet, I did what I wanted. I think I was too rushed so I asked here, but hopefully that's okay. It would be good to make this project to take less rows, so more answers will be appreciated, but I'm already happy with the functionality.
Anyways here's my code for the six buttons:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class project {
public static void main(String[] args) {
JFrame window = new JFrame("New window");
JButton button = new JButton ("Create");
button.setBounds(80,20,100,30);
JButton writeto = new JButton ("Write to file");
writeto.setBounds(80,80,100,30);
JButton close = new JButton ("Close");
close.setBounds(80,140,100,30);
JButton delete = new JButton ("Delete file");
delete.setBounds(80,200,100,30);
JTextField field = new JTextField();
field.setBounds(80,380,100,30);
JLabel text = new JLabel("Testing");
text.setBounds(110,440,100,30);
JButton writefrom = new JButton("Write from file");
writefrom.setBounds(80,260,120,30);
JPanel panel = new JPanel();
panel.setBounds(75,15,110,40);
JButton deletetext = new JButton("Delete");
deletetext.setBounds(80,320,100,30);
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
File file = new File("file.txt");
try {
if (file.createNewFile()) {
text.setText("Created");
}
else {
text.setText("Not created");
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
writeto.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
try {
FileWriter writeto = new FileWriter("file.txt");
writeto.write(field.getText());
writeto.close();
field.setText("");
text.setText("Task successful");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
text.setText("Task unsuccessful");
}
}
});
close.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
delete.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
File delete = new File("file.txt");
if (delete.delete()) {
text.setText("Deleted");
}
else {
text.setText("Not deleted");
}
}
});
writefrom.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
File writefrom = new File("file.txt");
try {
Scanner scanner = new Scanner(writefrom);
while (scanner.hasNextLine()) {
String data = scanner.nextLine();
field.setText(data);
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
panel.setBackground(Color.GREEN);
deletetext.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
try {
FileWriter deletetext = new FileWriter("file.txt");
deletetext.write("");
deletetext.close();
field.setText("");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
text.setText("Task unsuccessful");
}
}
});
window.add(button);
window.add(writeto);
window.add(close);
window.add(delete);
window.add(field);
window.add(text);
window.add(writefrom);
window.add(panel);
window.setLayout(null);
window.add(deletetext);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(300,600);
window.setVisible(true);
}
}
Below is my rewrite of your application. Note the following:
You should almost always use a layout manager (rather than setting the layout to null and calling method setBounds). In the below code I use BoxLayout.
After you read or writer a file, you should close it. In the below code I use try-with-resources to ensure that the file is closed.
Rather than using anonymous, inner classes to implement the ActionListeners, I use method references.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Project2 {
private static final String FILE_NAME = "file.txt";
private JLabel text;
private JTextField field;
private void addComponentToPanel(Component cmpt, JPanel panel) {
panel.add(cmpt);
panel.add(Box.createRigidArea(new Dimension(0, 10)));
}
private void close(ActionEvent event) {
System.exit(0);
}
private void createAndDisplayGui() {
JFrame window = new JFrame("New Window");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(createPanel(), BorderLayout.CENTER);
window.pack();
window.setLocationByPlatform(true);
window.setVisible(true);
}
private JButton createButton(String text,
int mnemonic,
String tooltip,
Dimension prefSize,
ActionListener listener) {
JButton button = new JButton(text);
button.setAlignmentX(Component.CENTER_ALIGNMENT);
if (prefSize != null) {
button.setMaximumSize(prefSize);
}
if (mnemonic > 0) {
button.setMnemonic(mnemonic);
}
if (tooltip != null && !tooltip.isEmpty()) {
button.setToolTipText(tooltip);
}
button.addActionListener(listener);
return button;
}
private void createFile(ActionEvent event) {
File file = new File(FILE_NAME);
try {
if (file.createNewFile()) {
text.setText("Created");
}
else {
text.setText("Not created");
}
}
catch (IOException e1) {
e1.printStackTrace();
}
}
private JPanel createPanel() {
JPanel panel = new JPanel();
BoxLayout layout = new BoxLayout(panel, BoxLayout.PAGE_AXIS);
panel.setLayout(layout);
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
JButton widest = createButton("Write from file",
KeyEvent.VK_F,
"Display file contents.",
null,
this::writeFrom);
Dimension dim = widest.getPreferredSize();
addComponentToPanel(createButton("Create",
KeyEvent.VK_R,
"Create file.",
dim,
this::createFile),
panel);
addComponentToPanel(createButton("Write to file",
KeyEvent.VK_T,
"Write entered text to file.",
dim,
this::writeTo),
panel);
addComponentToPanel(createButton("Close",
KeyEvent.VK_C,
"Close application.",
dim,
this::close),
panel);
addComponentToPanel(createButton("Delete file",
KeyEvent.VK_E,
"Delete the file.",
dim,
this::delete),
panel);
addComponentToPanel(widest, panel);
addComponentToPanel(createButton("Delete",
KeyEvent.VK_D,
"Delete file contents.",
dim,
this::deleteText),
panel);
field = new JTextField();
addComponentToPanel(field, panel);
text = new JLabel("Testing");
text.setAlignmentX(Component.CENTER_ALIGNMENT);
addComponentToPanel(text, panel);
return panel;
}
private void delete(ActionEvent event) {
File delete = new File(FILE_NAME);
if (delete.delete()) {
text.setText("Deleted");
}
else {
text.setText("Not deleted");
}
}
private void deleteText(ActionEvent event) {
try (FileWriter deletetext = new FileWriter(FILE_NAME)) {
deletetext.write("");
deletetext.close();
field.setText("");
}
catch (IOException e1) {
e1.printStackTrace();
text.setText("Task unsuccessful");
}
}
private void writeFrom(ActionEvent event) {
File writefrom = new File(FILE_NAME);
try (Scanner scanner = new Scanner(writefrom)) {
while (scanner.hasNextLine()) {
String data = scanner.nextLine();
field.setText(data);
}
}
catch (FileNotFoundException e1) {
e1.printStackTrace();
}
}
private void writeTo(ActionEvent event) {
try (FileWriter writeto = new FileWriter(FILE_NAME)) {
writeto.write(field.getText());
writeto.close();
field.setText("");
text.setText("Task successful");
}
catch (IOException e1) {
e1.printStackTrace();
text.setText("Task unsuccessful");
}
}
public static void main(String[] args) {
Project2 proj2 = new Project2();
EventQueue.invokeLater(() -> proj2.createAndDisplayGui());
}
}
This is how the GUI looks when I run the above code.
So, my program is a user adding buttons during runtime. When he/she clicks on the 'save' button the program is saved to a file. But when I run it again, the buttons are gone. I tried to serialize my buttons using XMLEncoder and XMLDecoder, but when I ran my program, it didn't save anything, it started all over again. How would I serialize this correctly so that when I start my program, the buttons are there? Any help would be appreciated.
Here is a snippet of my code:
public class saveButton
{
//JFrame and JPanels have been declared earlier
class ClickListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
str = JOptionPane.showInputDialog("What is the name of the new button?");
JButton b = new JButton(str);
frame.add(b);
try
{
XMLEncoder encdr = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("file.ser")));
encdr.writeObject(new JButton(str));
encdr.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
ActionListener addButtonClicked = new ClickListener();
b.addActionListener(addButtonClicked);
class ClickListenerTwo implements ActionListener
{
public void actionPerformed(ActionEvent f)
{
try
{
XMLDecoder d = new XMLDecoder(new BufferedInputStream(new FileInputStream("file.ser")));
Object result = d.readObject();
d.close();
}
catch (IOException decoder)
{
decoder.printStackTrace();
}
}
}
Once you decode the object, you need to cast the object appropriately and then add the component to the container.
This is pretty basic example which generates a random number of buttons on a panel each time you click the Random button. When you click Save, the panel is saved to disk and when you click Load, it loads the panel from disk and reapplies it the container
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private RandomButtonPane pane;
public TestPane() {
setLayout(new BorderLayout());
JPanel actions = new JPanel();
JButton random = new JButton("Random");
JButton save = new JButton("Save");
JButton load = new JButton("Load");
actions.add(random);
actions.add(save);
actions.add(load);
add(actions, BorderLayout.SOUTH);
random.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (pane != null) {
remove(pane);
}
pane = new RandomButtonPane();
pane.randomise();
add(pane);
Window window = SwingUtilities.windowForComponent(TestPane.this);
window.pack();
window.setLocationRelativeTo(null);
}
});
save.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (pane != null) {
try (OutputStream os = new FileOutputStream(new File("Save.dat"))) {
try (XMLEncoder encoder = new XMLEncoder(os)) {
encoder.writeObject(pane);
remove(pane);
pane = null;
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
});
load.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (pane != null) {
remove(pane);
pane = null;
}
try (InputStream is = new FileInputStream(new File("Save.dat"))) {
try (XMLDecoder decoder = new XMLDecoder(is)) {
Object value = decoder.readObject();
if (value instanceof RandomButtonPane) {
pane = (RandomButtonPane)value;
pane.revalidate();
add(pane);
}
}
} catch (IOException exp) {
exp.printStackTrace();
}
Window window = SwingUtilities.windowForComponent(TestPane.this);
window.pack();
window.setLocationRelativeTo(null);
}
});
}
}
public static class RandomButtonPane extends JPanel {
public RandomButtonPane() {
setLayout(new GridBagLayout());
}
public void randomise() {
int count = ((int) (Math.random() * 100)) + 1;
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
for (int index = 0; index < count; index++) {
if (index % 10 == 0) {
gbc.gridx = 0;
gbc.gridy++;
}
add(new JButton(Integer.toString(index)), gbc);
gbc.gridx++;
}
}
}
}
I work at a project and i need to understand very well how event-driven programming works. I've read a lot in the last few days and i understood how this is working but i cant figure some things out.
In a class called Application i got this:
public void Simulate() throws InterruptedException {
int i = 0;
while (1 == 1) {
System.out.println(i);
Thread.sleep(1000);
i++;
}
}
And i have this class:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JButton;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Visual {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Visual window = new Visual();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Visual() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 472, 381);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.NORTH);
JButton btnStart = new JButton("Start");
btnStart.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
Application app = new Application();
try {
app.Simulate();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
**JButton print = new JButton("Print");
print.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("random text");
}
});**
panel.add(print);
panel.add(btnStart);
}
}
What i want to do is when i run this program, i want to pres the putton Start to start the loop in the simulate method and then i want to press the button print, to print some random text while the counter is still running. The problem is that after i pres the start button, the print button becomes unavailable, and cant be pressed anymore. How can i solve this?
For buttons don't use addMouseListener, use addActionListener and override actionPerformed method, to be able to print your number while the loop is running, try to call your simulate method using new thread. Change your Visual class to the followng example:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Visual {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Visual window = new Visual();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Visual() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 472, 381);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.NORTH);
JButton btnStart = new JButton("Start");
btnStart.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
Application app = new Application();
(new Thread(new Runnable() {
public void run() {
try {
app.Simulate();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
})).start();
}
});
JButton print = new JButton("Print");
print.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("random text");
}
});
panel.add(print);
panel.add(btnStart);
}
}
How do I display a JLabel based on a combobox option. When I run the code all the JLabels are displayed straight away.
combo1.addActionListener(this);
panel.add(combo1);
panel.add(img1);
panel.add(img2);
panel.add(img3);
frame.add(panel);
img1.setText("<html> Image : Image1/</html>");
img2.setText("<html> Image : Image2/</html>");
img3.setText("<html> Image : Image3/</html>");
img1.setCursor(new Cursor(Cursor.HAND_CURSOR));
img2.setCursor(new Cursor(Cursor.HAND_CURSOR));
img3.setCursor(new Cursor(Cursor.HAND_CURSOR));
I'm using mouseListener to check which label is passed into the goWebsite() function, and then according to that it'll add a hyperlink to the label.
private void goWebsite(final JLabel website) {
website.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if(website == img1){
try {
Desktop.getDesktop().browse(new URI("http://2.bp.blogspot.com/_2dxp9ORKKAM/TBZpViy7O1I/AAAAAAAABGY/zitq3ZLA8K4/s1600/red.png"));
} catch (URISyntaxException | IOException ex) {
//It looks like there's a problem
}
}
if(website == img2){
try {
Desktop.getDesktop().browse(new URI("http://www.pratikbagaria.com/wp-content/uploads/2011/04/BlueGreenPink.jpg"));
} catch (URISyntaxException | IOException ex) {
//It looks like there's a problem
}
}
if(website == img3){
try {
Desktop.getDesktop().browse(new URI("http://i.imgur.com/9OPnZNk.png"));
} catch (URISyntaxException | IOException ex) {
//It looks like there's a problem
}
}
if(website == img4){
try {
Desktop.getDesktop().browse(new URI("http://www.solidbackgrounds.com/images/three/2048x2048/2048x2048-fluorescent-orange-fluorescent-pink-fluorescent-yellow-three-color-background.jpg"));
} catch (URISyntaxException | IOException ex) {
//It looks like there's a problem
}
}
The actionPerformed checks which option from the combobox the user has selected and then passes the right img JLabel into the goWebsite() function.
#Override
public void actionPerformed(ActionEvent e)
{
String color1 = (String)combo1.getSelectedItem();
// Possibly check if either color is 'null' here
if (color1.equals("red") )
{
goWebsite(img1);
}
if (color1.equals("blue") )
{
goWebsite(img2);
}
if (color1.equals("green") )
{
goWebsite(img3);
}
}
Try adding a ItemListener to the JComboBox, when itemStateChanged is called, check that the ItemEvent#getStateChanged equals ItemEvent.SELECTED.
Check what is selected in the combo box (or use ItemEvent#ItemSelected) and either update a single JLabel with the information you want OR make the current label associated with the selected item visible by using JLabel#setVisible(true), but also make sure you hide the others
For example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ComboBoxUpdate {
public static void main(String[] args) {
new ComboBoxUpdate();
}
public ComboBoxUpdate() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JComboBox comboBox;
private JLabel option1;
private JLabel option2;
private JLabel option3;
public TestPane() {
comboBox = new JComboBox(new String[]{"Choice 1", "Choice 2", "Choice 3"});
option1 = new JLabel("Bananas");
option2 = new JLabel("Appels");
option3 = new JLabel("Grapes");
option1.setVisible(false);
option2.setVisible(false);
option3.setVisible(false);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(comboBox, gbc);
add(option1, gbc);
add(option2, gbc);
add(option3, gbc);
comboBox.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
switch (e.getStateChange()) {
case ItemEvent.SELECTED:
Object value = comboBox.getSelectedItem();
option1.setVisible(false);
option2.setVisible(false);
option3.setVisible(false);
if ("Choice 1".equals(value)) {
option1.setVisible(true);
} else if ("Choice 2".equals(value)) {
option2.setVisible(true);
} else if ("Choice 3".equals(value)) {
option3.setVisible(true);
}
break;
}
}
});
comboBox.setSelectedItem(null);
}
}
}
I am trying to make a game like simon: http://www.freegames.ws/games/kidsgames/simon/simon.htm#
I am making a smaller scale with only 2 buttons. I want the color to switch between 2 buttons, button1 and button2. This is in a thread because I need buttons to be clicked while this is happening. When I open the program the button color stays as-is.
Thanks for help in advance!
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.*;
public class TestFrame extends JFrame{
public JButton button1;
public JButton button2;
boolean isTrue = true;
boolean switchColor = true;
TestFrame(){
super("Simon");
initialize();
this.setSize(200, 400);
this.setVisible(true);
}
private void initialize() {
this.setLayout(new BorderLayout());
button1 = new JButton();
button1.setBackground(Color.green);
button1.setSize(200,200);
button2 = new JButton();
button2.setSize(200, 200);
button2.setBackground(Color.blue);
this.add(button1, BorderLayout.NORTH);
this.add(button2, BorderLayout.SOUTH);
Thread t = new Thread(r1);
t.start();
}
Runnable r1 = new Runnable() {
public void run() {
while(isTrue){
if(switchColor = true){
button1.setBackground(Color.blue);
button2.setBackground(Color.green);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
refresh();
switchColor = false;
} else {
button1.setBackground(Color.green);
button2.setBackground(Color.blue);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
refresh();
switchColor = true;
}
}
}
};
public void refresh(){
this.invalidate();
this.validate();
this.repaint();
}
}
A number of issues stand out (shazin has addressed one), the other that scares me is you are violating the single thread requirements of Swing. All changes to the UI must be made from within the context of the Event Dispatching Thread.
Instead of using a Thread, you should be using a javax.swing.Timer. This will save you the need to have to resync your updates back to the EDT.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FlashyButtons {
public static void main(String[] args) {
new FlashyButtons();
}
public FlashyButtons() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton btn1;
private JButton btn2;
private int count = 0;
public TestPane() {
setLayout(new GridBagLayout());
btn1 = new FlashButton();
btn2 = new FlashButton();
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(btn1, gbc);
add(btn2, gbc);
btn1.setBackground(Color.GREEN);
btn2.setBackground(Color.BLUE);
Timer timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
count++;
if (count % 2 == 0) {
btn1.setBackground(Color.BLUE);
btn2.setBackground(Color.GREEN);
} else {
btn1.setBackground(Color.GREEN);
btn2.setBackground(Color.BLUE);
}
}
});
timer.start();
}
}
public class FlashButton extends JButton {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Take a look at Concurrency in Swing for more details
if(switchColor = true){
button1.setBackground(Color.blue);
button2.setBackground(Color.green);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
refresh();
switchColor = false;
} else {
button1.setBackground(Color.green);
button2.setBackground(Color.blue);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
refresh();
switchColor = true;
}
}
In the above code change the following to
if(switchColor = true){
to
if(switchColor == true){
or just
if(switchColor){
And it is best to have your Runnable anonymous class inside
SwingUtilities.invokeLater(new Runnable() {
public void run() {
}
});
than using a new Thread object to create and start the thread as it will be changing the Swing UI properties.