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++;
}
}
}
}
Related
I am trying to Show a background Image but it will not work, i have tried multiple things it comes back with this error ever time. Every time it says Duplicate field i don't know what that means I am a beginner in java
Here is the Error
Exception in thread "main" java.lang.ClassFormatError: Duplicate field name&signature in class file search/text/file/SearchTextFile$1
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at search.text.file.SearchTextFile.<init>(SearchTextFile.java:46)
at search.text.file.SearchTextFile.main(SearchTextFile.java:42)
Java Result: 1
And this try block causing background error :
try {
BufferedImage img = ImageIO.read(new File("bible.jpg"));
} catch(IOException e ) {
}
Thank You
Java Code:
package search.text.file;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.imageio.ImageIO;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SearchTextFile {
public static void main(String[] args) {
new SearchTextFile();
}
public SearchTextFile() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Bible Search");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
try {
BufferedImage img = ImageIO.read(new File("bible.jpg"));
} catch(IOException e ) {
}
});
}
public class TestPane extends JPanel {
private JTextField findText;
private JButton search;
private DefaultListModel<String> model;
private JList list;
private String searchPhrase;
public TestPane() {
setLayout(new BorderLayout());
JPanel searchPane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(2, 2, 2, 2);
searchPane.add(new JLabel("Find: "), gbc);
gbc.gridx++;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
findText = new JTextField(20);
searchPane.add(findText, gbc);
gbc.gridx++;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
search = new JButton("Search");
searchPane.add(search, gbc);
add(searchPane, BorderLayout.NORTH);
model = new DefaultListModel<>();
list = new JList(model);
list.setCellRenderer(new HighlightListCellRenderer());
add(new JScrollPane(list));
ActionHandler handler = new ActionHandler();
search.addActionListener(handler);
findText.addActionListener(handler);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("bible.txt")))) {
String text = null;
while ((text = reader.readLine()) != null) {
model.addElement(text);
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
public class ActionHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
searchPhrase = findText.getText();
if (searchPhrase != null && searchPhrase.trim().length() == 0) {
searchPhrase = null;
}
list.repaint();
// model.removeAllElements();
//// BufferedReader reader = null;
//
// String searchText = findText.getText();
// try (BufferedReader reader = new BufferedReader(new FileReader(new File("bible.txt")))) {
//
// String text = null;
// while ((text = reader.readLine()) != null) {
//
// if (text.contains(searchText)) {
//
// model.addElement(text);
//
// }
//
// }
//
// } catch (IOException exp) {
//
// exp.printStackTrace();
// JOptionPane.showMessageDialog(TestPane.this, "Something Went Wrong", "Error", JOptionPane.ERROR_MESSAGE);
//
// }
}
}
public class HighlightListCellRenderer extends DefaultListCellRenderer {
public final String WITH_DELIMITER = "((?<=%1$s)|(?=%1$s))";
#Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (value instanceof String && searchPhrase != null) {
String text = (String) value;
if (text.contains(searchPhrase)) {
text = text.replace(" ", " ");
value = "<html>" + text.replace(searchPhrase, "<span STYLE='background-color: #ffff00'>" + searchPhrase + "</span>") + "</html>";
}
}
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); //To change body of generated methods, choose Tools | Templates.
}
}
}
}
Your try block:
try {
BufferedImage img = ImageIO.read(new File("bible.jpg"));
} catch(IOException e ) {
}
});
is outside of any method or constructor, and this is not allowed. I suggest that you
move it to within a constructor or method.
Don't ignore the exceptions as you're doing as this is very dangerous coding. At least print out the exception's stack trace.
Also, why are you reading in an image but then doing nothing with it?
e.g.
public class SearchTextFile2 {
private static void createAndShowGui() {
BufferedImage img = null;
try {
// better to get as a resource and not as a File
img = ImageIO.read(new File("bible.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
JFrame frame = new JFrame("SearchTextFile2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TestPane(img)); // pass image into TestPane
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
// make TestPane a static inner class
// have TestPane display image within its paintComponent method
public static class TestPane extends JPanel {
private JTextField findText;
private JButton search;
private DefaultListModel<String> model;
private JList list;
private BufferedImage img;
private String searchPhrase;
public TestPane(BufferedImage img) {
setLayout(new BorderLayout());
this.img = img;
// etc.....
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
// .....
looks like all classes you placed in one file might be that would be messed in your case
please check java docs for error
Java Virtual Machine attempts to read a class file and determines that
the file is malformed or otherwise cannot be interpreted as a class
file
http://docs.oracle.com/javase/7/docs/api/java/lang/ClassFormatError.html
I have a JScrollPane which contains a JTextArea. When the window is minimized and then restored, the JScrollPane will then collapse on itself. Note that this squish only happens if the text in the JTextArea exceeds the given width and/or height of the JTextArea (i.e., the horizontal or vertical scrollbars appear).
This question here: JScrollpane loses size after minimize poses the same problem, but the issue is never addressed, other than to add weightx, weighty, and fill constraints to the JScrollPane, which I already had to begin with.
Below is a simplified example that demonstrates the problem. How can I get the JScrollPane to sustain its size after the window is minimized and restored?
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EtchedBorder;
public class GUITest implements ActionListener {
JButton button = new JButton("Button");
JTextArea textArea = new JTextArea();
SwingWorker<String, String> mySwingWorker = null;
public static void main(String[] args) throws IOException {
GUITest tracer = new GUITest();
}
public GUITest() throws IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
createAndShowGUI();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public void createAndShowGUI() throws IOException {
JFrame frame = new JFrame("GUI Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints mainPanelConstraints = new GridBagConstraints();
mainPanelConstraints.gridx = 0;
mainPanelConstraints.gridy = 0;
mainPanelConstraints.fill = GridBagConstraints.BOTH;
button.addActionListener(this);
mainPanel.add(button, mainPanelConstraints);
mainPanelConstraints.gridx = 0;
mainPanelConstraints.gridy = 1;
mainPanelConstraints.fill = GridBagConstraints.BOTH;
mainPanel.add(buildTextAreaPanel(), mainPanelConstraints);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setVisible(true);
}
private JPanel buildTextAreaPanel() {
JPanel textAreaPanel = new JPanel();
textAreaPanel.setLayout(new GridBagLayout());
GridBagConstraints textAreaPanelConstraints = new GridBagConstraints();
textAreaPanel.setBorder(BorderFactory.createTitledBorder(new EtchedBorder(EtchedBorder.RAISED), "TextArea"));
textArea.setColumns(30);
textArea.setRows(15);
textArea.setEditable(false);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
textAreaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
textAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
textAreaPanelConstraints.gridx = 0;
textAreaPanelConstraints.gridy = 0;
textAreaPanelConstraints.weightx = 1.0;
textAreaPanelConstraints.weighty = 1.0;
textAreaPanelConstraints.fill = GridBagConstraints.BOTH;
textAreaPanel.add(textAreaScrollPane, textAreaPanelConstraints);
return textAreaPanel;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
mySwingWorker = new MySwingWorker();
mySwingWorker.execute();
}
}
private class MySwingWorker extends SwingWorker<String, String> {
public String doInBackground() throws Exception {
for (int i = 0; i < textArea.getRows(); i++) {
publish("text\n");
}
publish("more text\n");
return "Done.";
}
public void process(List<String> chunks) {
for (String msg : chunks) {
textArea.append(msg);
}
}
public void done() {
try {
String msg = get();
textArea.append("\n" + msg);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
You need to set the weightx and weighty in both layouts. In createAndShowGui, set mainPanelConstraints.weightx and mainPanelConstraints.weighty to 1 before adding the text area panel.
Set the layout of the parent Container (the content pane) to FlowLayout
...
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(mainPanel);
...
I solved the shrinkage problem in this particular code example by removing all GridBagLayouts and replacing them with BorderLayouts. I have no idea why a JScrollPane reacts the way you discovered when using a GridBagLayout.
I felt real uncomfortable starting the Event Dispatch thread from the class constructor. I moved the SwingUtilities invokeLater into the main method.
Anyway, here's the code.
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EtchedBorder;
public class JScrollPaneTest implements ActionListener {
JButton button = new JButton("Button");
JTextArea textArea = new JTextArea();
SwingWorker<String, String> mySwingWorker = null;
public static void main(String[] args) throws IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new JScrollPaneTest().createAndShowGUI();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public JScrollPaneTest() throws IOException {
}
public void createAndShowGUI() throws IOException {
JFrame frame = new JFrame("JScrollPane Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
mainPanel.add(button, BorderLayout.NORTH);
mainPanel.add(buildTextAreaPanel(), BorderLayout.CENTER);
button.addActionListener(this);
frame.add(mainPanel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private JPanel buildTextAreaPanel() {
JPanel textAreaPanel = new JPanel();
textAreaPanel.setLayout(new BorderLayout());
textAreaPanel.setBorder(BorderFactory.createTitledBorder(
new EtchedBorder(EtchedBorder.RAISED), "TextArea"));
textArea.setColumns(30);
textArea.setRows(15);
textArea.setEditable(false);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
textAreaPanel.add(textAreaScrollPane, BorderLayout.CENTER);
return textAreaPanel;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
mySwingWorker = new MySwingWorker();
mySwingWorker.execute();
}
}
private class MySwingWorker extends SwingWorker<String, String> {
public String doInBackground() throws Exception {
for (int i = 0; i < textArea.getRows(); i++) {
publish("text\n");
}
publish("more text\n");
return "Done.";
}
public void process(List<String> chunks) {
for (String msg : chunks) {
textArea.append(msg);
}
}
public void done() {
try {
String msg = get();
textArea.append("\n" + msg);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
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.
I am using JProgressBar to show progress. But, How to show the progressBar as loading from 0 to 100? I got the code from internet and its working except the progressBar is not loading.
code
progressFrame = new JFrame(); // frame to display progress bar
progressBar = new JProgressBar(0,100);
progressBar.setValue(0);
progressBar.setStringPainted(true);
progressFrame.add(progressBar);
new SwingWorker<Void,Void>()
{
protected Void doInBackground() throws SQLException, ClassNotFoundException
{
Class.forName("oracle.jdbc.driver.OracleDriver");
progressBar.setValue(0);
frame.setEnabled(false); // frame = main frame
//tableclass creates a JTable with data from database
tableclass = new TheDatabaseTable(deptName);//it takes time to create
progressBar.setValue(50);
frame.getContentPane().removeAll();
frame.setContentPane(tableclass);
frame.validate();
frame.repaint();
progressBar.setValue(100);
//progressFrame.dispose();
return null;
};
protected void done()
{
//progressFrame.setVisible(false);
frame.setVisible(true);
progressFrame.dispose();
frame.setEnabled(true);
}
}.execute();
I would appreciate if anyone edit the above code to work. Thank you.
Gotta love code from the internet...oh...
The code you have violates the singe thread rules of Swing and thus, is a bad example.
You have a number of options with SwingWorker. You could publish the progress and use the process method to update the progress bar or you could use a PropertyChangeListener and monitor progress change events created by calling the setProgress method of the SwingWorker
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class SwingWorkerProgress {
public static void main(String[] args) {
new SwingWorkerProgress();
}
public SwingWorkerProgress() {
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 JProgressBar pbProgress;
private JButton start;
public TestPane() {
setBorder(new EmptyBorder(10, 10, 10, 10));
pbProgress = new JProgressBar();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
gbc.gridx = 0;
gbc.gridy = 0;
add(pbProgress, gbc);
start = new JButton("Start");
gbc.gridy++;
add(start, gbc);
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
start.setEnabled(false);
ProgressWorker pw = new ProgressWorker();
pw.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
String name = evt.getPropertyName();
if (name.equals("progress")) {
int progress = (int) evt.getNewValue();
pbProgress.setValue(progress);
repaint();
} else if (name.equals("state")) {
SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
switch (state) {
case DONE:
start.setEnabled(true);
break;
}
}
}
});
pw.execute();
}
});
}
}
public class ProgressWorker extends SwingWorker<Object, Object> {
#Override
protected Object doInBackground() throws Exception {
int i = 0;
int max = 2000;
while (i < max) {
i += 10;
int progress = Math.round(((float)i / (float)max) * 100f);
setProgress(progress);
try {
Thread.sleep(25);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
}
You have to use threads for that. Design a class that implements Runnable interface which will update the values like this.
class ProgressBarUpdator implements java.lang.Runnable {
/**
* Progress bar that shows the current status
*/
private javax.swing.JProgressBar jpb = null;
/**
* Progress bar value
*/
private java.lang.Integer value = null;
/**
* Constructor
* #param jpb The progress bar this has to update
*/
public ProgressBarUpdator(javax.swing.JProgressBar jpb) {
this.jpb = jpb;
jpb.setMaximum(100);
}
/**
* Sets the value to the progress bar
* #param value Value to set
*/
public void setValue(java.lang.Integer value) {
this.value = value;
}
/**
* Action of the thread will be executed here. The value of the progress bar will be set here.
*/
public void run() {
do {
if (value != null) {
jpb.setValue((int)java.lang.Math.round(java.lang.Math.floor(value.intValue() * 100 / maximum)));
}
try {
java.lang.Thread.sleep(100L);
} catch (java.lang.InterruptedException ex) {
ex.printStackTrace();
}
} while (value == null || value.intValue() < jpb.getMaximum());
}
}
and in your frame class use progressBar with the new class like this
ProgressBarUpdator ju = new ProgressBarUpdator(progressBar);
new java.lang.Thread(ju).start();
Whenever you want to change the value just use the statement
ju.setValue([Value to set]);
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
public class ProgressBar {
/**
* JProgressBar
*
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("New Window");
frame.setSize(600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setLayout(new GridBagLayout());
frame.setVisible(true);
//JLabel textLoad = new JLabel();
//textLoad.setText("Loading ....");
JProgressBar progressBar = new JProgressBar();
progressBar.setMinimum(0);
progressBar.setMaximum(100);
progressBar.setStringPainted(true);
progressBar.setIndeterminate(true);
frame.add(progressBar);
for (int i = progressBar.getMinimum(); i <= progressBar.getMaximum(); i++) {
Thread.sleep(500);
progressBar.setValue(i);
}
textLoad.setText("Done !");
}
}
/*
By
Dr. Amit Kumar Kapoor
Assistant Professor, Maharaja Agrasen Institute of Management & Technology, Jagadhri
E-mail ID: akbrightfuture#gmail.com
*/
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class progressbardemo extends JFrame implements ActionListener
{
JProgressBar pb;
JButton b1;
progressbardemo()
{
super("Progressbar");
setLayout(null);
b1=new JButton("Click");
b1.setBackground(Color.yellow);
pb=new JProgressBar(1,100);
pb.setValue(0);
pb.setStringPainted(true);
pb.setForeground(Color.red);
pb.setBackground(Color.white);
b1.setBounds(20,20,80,25);pb.setBounds(110,20,200,25);
pb.setVisible(false);
add(b1);
add(pb);
b1.addActionListener(this);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e)
{
int i=0;
if(e.getSource()==b1)
{
pb.setVisible(true);
try
{
while(i<=100)
{
Thread.sleep(50);
pb.paintImmediately(0, 0, 200, 25);
pb.setValue(i);
i++;
}
}
catch(Exception e1)
{
System.out.print("Caughted exception is ="+e1);
}
}
}
public static void main(String arg[])
{
progressbardemo m=new progressbardemo();
m.setSize(330,100);
m.setVisible(true);
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((dimension.getWidth() - m.getWidth()) / 2);
int y = (int) ((dimension.getHeight() - m.getHeight()) / 2);
m.setLocation(x, y);
}
}