Java Applet - For Loop to decrement a stack of components - java

I've created an Applet that creates a row of buttons, up to 15 buttons, when you push the "add to queue" button. I now want to decrement that row using a for loop. I want it to decrement from left to right. I can only get it to decrement from right to left. I know it has to do with the code in my "Remove" method, but I can't seem to figure out how to fix it. As a newbie I would appreciate any help you can provide.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public class Main extends javax.swing.JApplet {
private final int width = 60;
private final int height = 24;
private final int maxItems = 15;
private int x = 40 + width;
private int y = 260;
private int count = 1;
private JButton jAdd;
private JButton jRemove;
Vector<JButton> stack = new Vector<JButton>();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
Main inst = new Main();
frame.getContentPane().add(inst);
((JComponent) frame.getContentPane()).setPreferredSize(inst
.getSize());
frame.pack();
frame.setVisible(true);
}
});
}
public Main() {
super();
initGUI();
}
private void initGUI() {
try {
this.setSize(719, 333);
getContentPane().setLayout(null);
{
jAdd = new JButton();
getContentPane().add(jAdd);
jAdd.setText("Add to Queue");
jAdd.setBounds(43, 300, 150, 24);
jAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jAddActionPerformed(evt);
}
});
}
{
jRemove = new JButton();
getContentPane().add(jRemove);
jRemove.setText("Remove from queue");
jRemove.setBounds(950, 300, 150, 24);
jRemove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jRemoveActionPerformed(evt);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void jAddActionPerformed(ActionEvent evt) {
if (count > maxItems) {
JOptionPane.showMessageDialog(null, "The queue is full");
return;
}
JButton b = new JButton();
stack.add(0, b);
getContentPane().add(b);
int textCount = count;
b.setText("" +textCount++);
b.setBounds(x, y, width, height);
x = x + width;
count++;
}
private void jRemoveActionPerformed(ActionEvent evt) {
if (stack.isEmpty()) {
JOptionPane.showMessageDialog(null, "The queue is empty");
return;
}
JButton b = stack.remove(0);
this.remove(b);
for(int originalX = 880; originalX < 880; originalX--){
x = 880 - width;
}
repaint();
count--;
}
}

The issue is this:
stack.add(0, b);
You are always adding the new one to the start of the Vector (index 0). Remove that and you will see the behavior you want.
stack.add(b);

Related

Cant change java button color after resetting button array

Im creating a program in which I must from time to time reset a button Array and display it on a jPanel. The function below adds the jButtons to my panel and displays them perfectly the first time that it is called, but from then on, every time I call it (after emptying the jButton array and applying .removeAll() to the panel) it wont let me change the background color of the jButton. Some assistance to help me find out why this is would be great, thanks.
import java.awt.*;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import javafx.scene.layout.Border;
import javax.swing.*;
/**
*
* #author Luis
*/
public class MineSweeper extends JFrame implements ActionListener {
int int_dim = 11;
int int_cellsShown = 0;
JButton[][] arr_btnField = new JButton[int_dim][int_dim];
int[][] arr_solution = new int[int_dim][int_dim];
Color[] clr_palette = {Color.white, new Color(0X00, 0X94, 0XFF), new Color(0X00, 0X26, 0XFF), new Color(0X00, 0XAA, 0X0A), Color.red, Color.MAGENTA, new Color(0XFF, 0X00, 0X00), new Color(0X9B, 0X00, 0X00)};
boolean bool_change = false;
boolean bool_won = false;
boolean bool_firstround = false;
javax.swing.border.Border border = BorderFactory.createLineBorder(Color.darkGray, 1, true);
MenuBar menu_bar;
Menu menu;
MenuItem optionNew;
//boolean[][] arr_boolShowed=new boolean[int_dim][int_dim];
int int_mines = 8;
ArrayList<Integer> arl_field = new ArrayList<Integer>();
JPanel jpanel = new JPanel();
JPanel jpanel2 = new JPanel();
//ArrayList<Boolean> arl_boolShowed = new ArrayList<Boolean>();
/**
* #param args the command line arguments
*/
public MineSweeper() throws FontFormatException, IOException {
resetGame();
//JFrame frame = new JFrame("");
this.getContentPane().add(jpanel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(true);
this.setTitle("Minesweeper");
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setSize(500, 500);
menu_bar = new MenuBar();
menu = new Menu("File");
optionNew = new MenuItem("Win");
optionNew.addActionListener(this);
menu.add(optionNew);
menu_bar.add(menu);
this.setMenuBar(menu_bar);
}
public void resetGame() {
jpanel.removeAll();
arl_field.clear();
arr_btnField = new JButton[int_dim][int_dim];
arr_solution = new int[int_dim][int_dim];
bool_change = false;
bool_won = false;
//arl_field = new ArrayList<Integer>();
for (int i = 0; i < arr_solution.length; i++) {
for (int j = 0; j < arr_solution[i].length; j++) {
arr_solution[i][j] = 1;
}
}
jpanel.setLayout(new GridLayout(0, int_dim));//if(bool_firstround==false)jpanel.setLayout(new GridLayout(0,int_dim));
for (int i = 0; i < arr_btnField.length; i++) {
for (int j = 0; j < arr_btnField[i].length; j++) {
arr_btnField[i][j] = new JButton();////if(bool_firstround==false)arr_btnField[i][j] = new JButton();//arl_field.get(i*int_dim+j)+"");
arr_btnField[i][j].setText("");
arr_btnField[i][j].setBackground(new Color(0X00, 0X94, 0XFF));
arr_btnField[i][j].setBorder(border);
arr_btnField[i][j].setForeground(clr_palette[1]);
arr_btnField[i][j].addMouseListener(listener);
arr_btnField[i][j].setFocusable(false);
jpanel.add(arr_btnField[i][j]);
}
}
jpanel.revalidate();
jpanel.repaint();
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new MineSweeper();
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
}
});
}
MouseListener listener = new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
outerloop:
for (int i = 0; i < arr_btnField.length; i++) {
for (int j = 0; j < arr_btnField[i].length; j++) {
if (e.getSource() == arr_btnField[i][j]) {
if (SwingUtilities.isLeftMouseButton(e)) {
labelText(i, j);
}
if (SwingUtilities.isRightMouseButton(e)) {
arr_btnField[i][j].setBackground(Color.red);
}
//bool_won=false;
break outerloop;
}
}
}
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
if (bool_won == true)
gameWon();
}
#Override
public void mouseExited(MouseEvent e) {
}
};
public void labelText(int i, int j) {
if (bool_won == false) {
arr_btnField[i][j].setText("1");
arr_btnField[i][j].setBackground(Color.white);
if (arr_btnField[i][j].getBorder() == border) {
int_cellsShown++;
System.out.println("Cells shown: " + int_cellsShown);
if (int_cellsShown >= (int_dim * int_dim - int_mines)) {
bool_won = true;
}
}
if (bool_won == false)
arr_btnField[i][j].setBorder(BorderFactory.createLineBorder(Color.darkGray, 1, true));
}
}
public void gameWon() {
int dialogResult = JOptionPane.showConfirmDialog(null, "You Won! Do you want to start a new game?", "Congratulations!", JOptionPane.YES_NO_OPTION);
if (dialogResult == JOptionPane.YES_OPTION) {
bool_won = false;
int_cellsShown = 0;
resetGame();
}
}
#Override
public void actionPerformed(ActionEvent e) {
int_cellsShown = 0;
int_dim++;
resetGame();
for (int i = 0; i < arr_btnField.length; i++) {
for (int j = 0; j < arr_btnField[i].length; j++) {
arr_btnField[i][j].setBackground(Color.red);
}
}
}
}
Display after the first time:
Display after the second time:
I invoke .revalidate in the fourth line of the method.
That doesn't do anything since there on no components added to the panel. The revalidate() needs to be done AFTER the components have been added.
The displayed panel is not jpanel, the displayed panel is jpanel2, thats why I assign jpanel2 to the value of jpanel in the end of the method.
You can't just change a reference and expect the components to be moved from one panel to another.
The components need to be added to the panel that is added to the GUI.
Edit:
First of all Swing components start with "J". Don't use AWT components (MenuBar, Menu, MenuItem) in a Swing application.
The problem is your LAF:
new MineSweeper();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
The components are created with the current LAF. When you first create the game, the default LAF is used to create all the buttons (and other components). This LAF allows you to change the background color of the buttons.
However, then you change the LAF. So when you reset the game board the buttons are now created with the System LAF. This LAF apparently does not allow you to change the background color of the button.
This should be easy to test. Create a GUI:
//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JButton button = new JButton("testing");
button.setBackground(Color.RED);
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( button );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
First test the code as above to see if the background of the button changes.
Then uncomment the LAF change and retest.
A possible solution so you are not dependent on the LAF is to use an Icon to represent the background color of the button. Then you can center any text on top of the Icon. Something like:
import java.awt.*;
import javax.swing.*;
public class ColorIcon implements Icon
{
private Color color;
private int width;
private int height;
public ColorIcon(Color color, int width, int height)
{
this.color = color;
this.width = width;
this.height = height;
}
public int getIconWidth()
{
return width;
}
public int getIconHeight()
{
return height;
}
public void paintIcon(Component c, Graphics g, int x, int y)
{
g.setColor(color);
g.fillRect(x, y, width, height);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI()
{
JPanel panel = new JPanel( new GridLayout(2, 2) );
for (int i = 0; i < 4; i++)
{
Icon icon = new ColorIcon(Color.RED, 50, 50);
JLabel label = new JLabel( icon );
label.setText("" + i);
label.setHorizontalTextPosition(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.CENTER);
panel.add(label);
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(panel);
f.setSize(200, 200);
f.setLocationRelativeTo( null );
f.setVisible(true);
}
}
Yep, I too just noticed, that the problem is here:
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new MineSweeper();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
}
});
}
If you comment out the UIManager line, your code works. This line is only valid after the GUI has been created, and so doesn't take effect until new components are created. Note that I was working on minimizing your code to discover this, and was cutting out code to see what caused the problem until this was all that was left.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.UIManager;
#SuppressWarnings("serial")
public class MineSweeper extends JFrame implements ActionListener {
private static final Color BTN_COLOR = new Color(0X00, 0X94, 0XFF);
int int_dim = 11;
JButton[][] arr_btnField = new JButton[int_dim][int_dim];
JMenuBar menu_bar;
JMenu menu;
JMenuItem optionNew;
JPanel jpanel = new JPanel();
public MineSweeper() {
resetGame();
this.getContentPane().add(jpanel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(true);
this.setTitle("Minesweeper");
menu_bar = new JMenuBar();
menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
optionNew = new JMenuItem("Win");
optionNew.setMnemonic(KeyEvent.VK_W);
optionNew.addActionListener(this);
menu.add(optionNew);
menu_bar.add(menu);
this.setJMenuBar(menu_bar);
this.setPreferredSize(new Dimension(500, 500));
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public void resetGame() {
jpanel.removeAll();
arr_btnField = new JButton[int_dim][int_dim];
jpanel.setLayout(new GridLayout(0, int_dim));
for (int i = 0; i < arr_btnField.length; i++) {
for (int j = 0; j < arr_btnField[i].length; j++) {
arr_btnField[i][j] = new JButton();
arr_btnField[i][j].setBackground(BTN_COLOR);
jpanel.add(arr_btnField[i][j]);
}
}
jpanel.revalidate();
jpanel.repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
resetGame();
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new MineSweeper();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
}
});
}
}

I get a stack overflow error

I'm trying to create a program where you press start and a new JFrame comes up with 3 buttons , you have to switch the button after you click on it using a random , I'm fairly new to java so I don't know what to do. Thank you
package code;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;
public class StartListener implements java.awt.event.ActionListener {
private int counter;
private Game Ga;
private JFrame z;
private int x;
public StartListener(Game a, int co){
Ga=a;
counter = co;
}
public void actionPerformed(ActionEvent e) {
Timer time = new Timer(10000,new Time(Ga));
time.start();
z = new JFrame("Sequence game");
FlowLayout fl = new FlowLayout(0, 50, 40);
z.getContentPane().setLayout(fl);
z.setVisible(true);
JButton a = new JButton("A");
Font f = a.getFont();
Font myFont = f.deriveFont(Font.BOLD, f.getSize()*4);
a.setSize(200,100);
a.setVisible(true);
JButton b = new JButton("B");
b.setVisible(true);
b.setSize(200,100);
JButton c = new JButton("C");
c.setVisible(true);
c.setSize(200,100);
z.getContentPane().add(a);
z.getContentPane().add(b);
z.getContentPane().add(c);
z.pack();
Random r = new Random();
x=r.nextInt(3);
figure(a,b,c,x,myFont,f);}
public void figure(JButton a,JButton b, JButton c, int x, Font myFont,Font f){
if(x==0){
a.setEnabled(true);
b.setEnabled(false);
c.setEnabled(false);
a.setFont(myFont);
b.setFont(f);
c.setFont(f);
x =buttonA(a);
figure(a,b,c,x,myFont,f);
;}
else if(x==1){
a.setEnabled(false);
b.setEnabled(true);
c.setEnabled(false);
a.setFont(f);
c.setFont(f);
b.setFont(myFont);
x = buttonB(b);
figure(a,b,c,x,myFont,f);
}
else if(x==2){
a.setEnabled(false);
b.setEnabled(false);
c.setEnabled(true);
a.setFont(f);
b.setFont(f);
c.setFont(myFont);
x = buttonC(c);
figure(a,b,c,x,myFont,f);
}
}
public int buttonA(JButton a){
Random r = new Random();
int rand = 0;
a.addActionListener(new Something(Ga));
rand = r.nextInt(3);
return rand;
}
public int buttonB(JButton b){
Random r = new Random();
int rand = 0;
b.addActionListener(new Something(Ga));
rand=r.nextInt(3);
return rand;
}
public int buttonC(JButton c){
Random r = new Random();
int rand=0;
c.addActionListener(new Something(Ga));
rand = r.nextInt(3);
return rand;
}
}
And here's the code for Something
package code;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Something implements ActionListener {
private Game G;
public Something(Game a){
G = a;
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
G.increment();
}
}
Here's the error :
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.awt.Component.enable(Unknown Source)
at java.awt.Component.setEnabled(Unknown Source)
at javax.swing.JComponent.setEnabled(Unknown Source)
at javax.swing.AbstractButton.setEnabled(Unknown Source)
Your figure method continuously calls itself recursively forever, or until stack space runs out. Solution: get rid of those recursive calls. Also you really don't want to keep adding multiple ActionListeners on to JButtons, all this suggesting that you will want to refactor and perhaps redesign the entire program.
You will want to change the state of a field in the class, and use that field's state to decide what to do within the ActionListener.
For example:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class SwapButtons extends JPanel {
private static final Font ACTIVE_FONT = new Font(Font.DIALOG, Font.BOLD, 15);
private static final String[] BTN_TEXT = { "Monday", "Tuesday", "Wednesday" };
private static final int EXTRA_WIDTH = 50;
private List<AbstractButton> buttonList = new ArrayList<>();
private int buttonIndex = 0;
public SwapButtons() {
setLayout(new GridLayout(1, 0, 5, 0));
BtnListener btnListener = new BtnListener();
for (int i = 0; i < BTN_TEXT.length; i++) {
JButton button = new JButton(BTN_TEXT[i]);
button.addActionListener(btnListener);
buttonList.add(button); // add to ArrayList
add(button); // add to GUI
}
setActiveButton();
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
}
#Override
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
// give preferred size extra width so gui can handle larger fonts
int prefW = superSz.width + EXTRA_WIDTH;
int prefH = superSz.height;
return new Dimension(prefW, prefH);
}
private void setActiveButton() {
// iterate through buttonList, turning on the "active" button
// as determined by the buttonIndex variable
for (int i = 0; i < buttonList.size(); i++) {
if (i == buttonIndex) {
buttonList.get(i).setFont(ACTIVE_FONT);
buttonList.get(i).setEnabled(true);
} else {
buttonList.get(i).setFont(null);
buttonList.get(i).setEnabled(false);
}
}
}
private class BtnListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// show which button pressed
System.out.println("Button Pressed: " + e.getActionCommand());
// advance button index so that next button can be activated
buttonIndex++;
// but change index to 0 if buttonList size is reached
buttonIndex %= buttonList.size();
// activate the next button:
setActiveButton();
}
}
private static void createAndShowGui() {
SwapButtons mainPanel = new SwapButtons();
JFrame frame = new JFrame("Swap Buttons");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Is java swing not working in java 8 update 45?

The following code is working in jdk 1.8 update 45 and in java 1.8 update 31 but NOT in java 1.8 update 45.
The program is a button moving back and forth until the user presses the button and makes it stop and the text is changed to "MOVE". When the button is pressed again, the button starts moving and the text is changed to "STOP".
In java 8 update 45, the button does not start moving but the text changes. Why?
package mainpackage;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class mainPanel implements ActionListener {
JFrame frame1;
JPanel panel1;
JButton button = new JButton("STOP");
boolean buttonPressed = false;
boolean move = true;
// 0 = left & 1 = right
int direction = 1;
int x = 0;
public static void main(String[] args) {
new mainPanel().loadGUI();
}
public void loadGUI() {
frame1 = new JFrame("Moving button");
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setVisible(true);
frame1.setSize(300, 58);
frame1.setResizable(false);
panel1 = new JPanel(); // Xwidth=294, Yheight=272
panel1.setSize(300, 30);
panel1.setLayout(null);
frame1.add(panel1);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame1.setLocation(dim.width/2-frame1.getSize().width/2, dim.height/2-frame1.getSize().height/2);
button.setSize(80, 30); //X, Y
panel1.add(button);
button.addActionListener(this);
while(true) moveButton();
}
public void moveButton() {
while(move == true) {
switch(direction) {
// left
case 0: {
while(x > 0) {
if(move == false) break;
button.setLocation(x, 0);
x--;
panel1.repaint();
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(mainPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
if(buttonPressed == true) {
direction = 0;
buttonPressed = false;
} else if(buttonPressed == false) {
direction = 1;
buttonPressed = false;
}
}
// right
case 1: {
while(x < panel1.getWidth() - button.getWidth()) {
if(move == false) break;
button.setLocation(x, 0);
x++;
panel1.repaint();
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(mainPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
if(buttonPressed == true) {
direction = 1;
buttonPressed=false;
} else if(buttonPressed == false) {
direction=0;
buttonPressed=false;
}
}
}
}
}
#Override
public void actionPerformed(ActionEvent e) {
if (move == true){
move=false;
} else if (move == false) {
move=true;
}
buttonPressed = true;
if((button.getText()).equals("STOP")) {
button.setText("MOVE");
} else button.setText("STOP");
}
}
Yours is broken code to begin with since it ignores Swing threading rules, and frankly I'm surprised that it worked in previous versions of Java. You're calling a while (true) loop that will tie up any thread that it is called in. Java 8 is correctly trying to start your Swing GUI on the Swing event thread, something that all Swing programs should do. If you get rid of the while (true) loops that risk being called on the Swing event dispatch thread, and instead use a Swing Timer your code should work. The Timer will run a loop in a background thread, but all code called repeatedly in its ActionListener will be called on the Swing event thread.
For example:
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MyMainPanel extends JPanel {
private static final int PREF_W = 300;
private static final int PREF_H = 30;
private static final int TIMER_DELAY = 20;
public static final int DELTA_X = 3;
private JButton moveButton = new JButton(new MoveButtonAction("Move"));
private Timer moveTimer = new Timer(TIMER_DELAY, new MoveTimerListener());
private boolean moveRight = true;
public MyMainPanel() {
moveButton.setSize(moveButton.getPreferredSize());
int y = (getPreferredSize().height - moveButton.getPreferredSize().height) / 2;
moveButton.setLocation(0, y);
setLayout(null); // !! lord I hate this
add(moveButton);
moveTimer.start();
}
#Override
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
int prefW = Math.max(superSz.width, PREF_W);
int prefH = Math.max(superSz.height, PREF_H);
return new Dimension(prefW, prefH);
}
private class MoveButtonAction extends AbstractAction {
public MoveButtonAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
moveRight = !moveRight;
}
}
private class MoveTimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (moveRight) {
if (moveButton.getLocation().x + moveButton.getWidth() >= getWidth()) {
moveRight = false;
}
} else {
if (moveButton.getLocation().x <= 0) {
moveRight = true;
}
}
int x = moveButton.getLocation().x + (moveRight ? DELTA_X : -DELTA_X);
int y = moveButton.getLocation().y;
moveButton.setLocation(new Point(x, y));
repaint();
}
}
private static void createAndShowGui() {
MyMainPanel mainPanel = new MyMainPanel();
JFrame frame = new JFrame("GUI Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
You will want to read up on Swing thread safety to see why your program is failing. See Lesson: Concurrency in Swing to see more on this.
Edit: code that stops and starts movement:
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
#SuppressWarnings("serial")
public class MyMainPanel extends JPanel {
private static final String MOVE = "Move";
private static final String STOP = "Stop";
private static final int PREF_W = 300;
private static final int PREF_H = 30;
private static final int TIMER_DELAY = 20;
public static final int DELTA_X = 3;
private MoveButtonAction moveButtonAction = new MoveButtonAction(STOP);
private JButton moveButton = new JButton(moveButtonAction);
private Timer moveTimer = new Timer(TIMER_DELAY, new MoveTimerListener());
private boolean moveRight = true;
public MyMainPanel() {
moveButton.setSize(moveButton.getPreferredSize());
int y = (getPreferredSize().height - moveButton.getPreferredSize().height) / 2;
moveButton.setLocation(0, y);
setLayout(null); // !! lord I hate this
add(moveButton);
moveTimer.start();
}
#Override
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
int prefW = Math.max(superSz.width, PREF_W);
int prefH = Math.max(superSz.height, PREF_H);
return new Dimension(prefW, prefH);
}
private class MoveButtonAction extends AbstractAction {
public MoveButtonAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
if (MOVE.equals(getValue(NAME))) {
moveTimer.start();
putValue(NAME, STOP);
int mnemonic = (int) STOP.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
} else {
moveTimer.stop();
putValue(NAME, MOVE);
int mnemonic = (int) MOVE.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
AbstractButton button = (AbstractButton) e.getSource();
button.setSize(button.getPreferredSize());
repaint();
}
}
private class MoveTimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (moveRight) {
if (moveButton.getLocation().x + moveButton.getWidth() >= getWidth()) {
moveRight = false;
}
} else {
if (moveButton.getLocation().x <= 0) {
moveRight = true;
}
}
int x = moveButton.getLocation().x + (moveRight ? DELTA_X : -DELTA_X);
int y = moveButton.getLocation().y;
moveButton.setLocation(new Point(x, y));
repaint();
}
}
private static void createAndShowGui() {
MyMainPanel mainPanel = new MyMainPanel();
JFrame frame = new JFrame("GUI Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Just added some methods and fixed some lines in your code, you can try it now:
import java.awt.Dimension;
import java.awt.Toolkit;
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;
public class mainPanel implements ActionListener {
JFrame frame1;
JPanel panel1;
JButton button = new JButton("START");
boolean buttonPressed = false;
boolean move = false;
Timer timer;
int direction = 1;
int x = 0;
public static void main(String[] args) {
new mainPanel().loadGUI();
}
public void loadGUI() {
frame1 = new JFrame("Moving button");
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setVisible(true);
frame1.setSize(300, 58);
frame1.setResizable(false);
panel1 = new JPanel(); // Xwidth=294, Yheight=272
panel1.setSize(300, 30);
panel1.setLayout(null);
frame1.add(panel1);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame1.setLocation(dim.width / 2 - frame1.getSize().width / 2, dim.height / 2 - frame1.getSize().height / 2);
button.setSize(80, 30); //X, Y
panel1.add(button);
button.addActionListener(this);
moveButton();
}
public void moveButton() {
if (timer == null) {
initTimer();
}
move = !move;
if (move) {
button.setText("STOP");
direction = (direction == 0) ? 1 : 0;
timer.start();
} else {
button.setText("MOVE");
timer.stop();
}
}
public void initTimer() {
timer = new Timer(10, (e) -> {
switch (direction) {
case 0: // right
x++;
if (x >= panel1.getWidth() - button.getWidth()) {
direction = 1;
}
break;
case 1: // left
x--;
if (x <= 0) {
direction = 0;
}
break;
}
button.setLocation(x, 0);
panel1.repaint();
});
}
#Override
public void actionPerformed(ActionEvent e) {
moveButton();
}
}

How to Change the Clockface of an Analog Clock Using BufferedImage in Java

Am trying to modify a java code that implements Analog Clock using BufferedImage. I want the face of the clock to be changed dynamically when a user clicks on a button that scrolls through an array preloaded with the locations of images. So far my attempts have failed. I have two classes; The first Class creates and displays the Analog, and the second class attempts to change the face of the Analog clock using a mutator (setAnalogClockFace()) and an accessor (getAnalogClockFace()). The following is the code for the first Class as found on here, with minor modifications:
package panels;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.util.*;
public class Clock extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
private int hours = 0;
private int minutes = 0;
private int seconds = 0;
private int millis = 0;
private static final int spacing = 10;
private static final float threePi = (float)(3.0 * Math.PI);
private static final float radPerSecMin = (float)(Math.PI/30.0);
private int size; //height and width of clockface
private int centerX;//X coord of middle of clock
private int centerY;//Y coord of middle of clock
private BufferedImage clockImage;
private BufferedImage imageToUse;
private javax.swing.Timer t;
public Clock(){
this.setPreferredSize(new Dimension(203,203));
this.setBackground(getBackground());
this.setForeground(Color.darkGray);
t = new javax.swing.Timer(1000, new ActionListener(){
public void actionPerformed(ActionEvent ae){
update();
}
});
}
public void update(){
this.repaint();
}
public void start(){
t.start();
}
public void stop(){
t.stop();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int w = getWidth();
int h = getHeight();
size = ((w < h) ? w : h) - 2 * spacing;
centerX = size/2 + spacing;
centerY = size/2 + spacing;
setClockFace(new AnalogClockTimer().getAnalogClockFace());
clockImage = getClockFace();
if (clockImage == null | clockImage.getWidth() != w | clockImage.getHeight() != h){
clockImage = (BufferedImage)(this.createImage(w,h));
Graphics2D gc = clockImage.createGraphics();
gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawClockFace(gc);
}
Calendar now = Calendar.getInstance();
hours = now.get(Calendar.HOUR);
minutes = now.get(Calendar.MINUTE);
seconds = now.get(Calendar.SECOND);
millis = now.get(Calendar.MILLISECOND);
g2d.drawImage(clockImage, null, 0, 0);
drawClockHands(g);
}
private void drawClockHands(Graphics g){
int secondRadius = size/2;
int minuteRadius = secondRadius * 3/4;
int hourRadius = secondRadius/2;
float fseconds = seconds + (float)millis/1000;
float secondAngle = threePi - (radPerSecMin * fseconds);
drawRadius(g, centerX, centerY, secondAngle, 0, secondRadius);
float fminutes = (float)(minutes + fseconds/60.0);
float minuteAngle = threePi - (radPerSecMin * fminutes);
drawRadius(g, centerX, centerY, minuteAngle, 0 , minuteRadius);
float fhours = (float)(hours + fminutes/60.0);
float hourAngle = threePi - (5 * radPerSecMin * fhours);
drawRadius(g, centerX, centerY, hourAngle, 0 ,hourRadius);
}
private void drawClockFace(Graphics g){
//g.setColor(Color.lightGray);
g.fillOval(spacing, spacing, size, size);
//g.setColor(new Color(168,168,168));
g.drawOval(spacing, spacing, size, size);
for(int sec = 0; sec < 60; sec++){
int tickStart;
if(sec%5 == 0){
tickStart = size/2-10;
}else{
tickStart = size/2-5;
}
drawRadius(g, centerX, centerY, radPerSecMin * sec, tickStart, size/2);
}
}
private void drawRadius(Graphics g, int x, int y, double angle,
int minRadius, int maxRadius){
float sine = (float)Math.sin(angle);
float cosine = (float)Math.cos(angle);
int dxmin = (int)(minRadius * sine);
int dymin = (int)(minRadius * cosine);
int dxmax = (int)(maxRadius * sine);
int dymax = (int)(maxRadius * cosine);
g.drawLine(x+dxmin, y+dymin, x+dxmax,y+dymax);
}
public void setClockFace(BufferedImage img){
if(img != null){
imageToUse = img;
}else{
try{
imageToUse =
ImageIO.read(getClass().getClassLoader().getResource("http://imgur.com/T8x0I29"));
}catch(IOException io){
io.printStackTrace();
}
}
}
public BufferedImage getClockFace(){
return imageToUse;
}
}
The second Class that attempts to set the Clock face is:
package panels;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import panels.Clock;
public class AnalogClockTimer extends javax.swing.JPanel implements ActionListener,
MouseListener {
private Clock clock;
/**
*
*/
private static final long serialVersionUID = 1L;
private JButton prevBtn;
private JTextField clockFaceCount;
private JButton nextBtn;
private JPanel buttonedPanel,leftPanel,rightPanel;
private BufferedImage image;
String[] clockFace;
int arrayPointer = 1;
/**
* Auto-generated main method to display this
* JPanel inside a new JFrame.
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new AnalogClockTimer());
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public AnalogClockTimer() {
super();
initGUI();
}
private void initGUI() {
try {
BorderLayout thisLayout = new BorderLayout();
this.setLayout(thisLayout);
this.setPreferredSize(new java.awt.Dimension(283, 233));
this.setBackground(getBackground());
{
clock = new Clock();
add(clock,BorderLayout.CENTER);
clock.start();
clock.setSize(203, 203);
}
{
buttonedPanel = new JPanel();
FlowLayout buttonedPanelLayout = new FlowLayout();
buttonedPanel.setLayout(buttonedPanelLayout);
this.add(buttonedPanel, BorderLayout.SOUTH);
buttonedPanel.setPreferredSize(new java.awt.Dimension(283, 30));
{
prevBtn = new JButton(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_rest.png")));
prevBtn.setPreferredSize(new java.awt.Dimension(20, 19));
prevBtn.setBackground(getBackground());
prevBtn.setBorderPainted(false);
prevBtn.setEnabled(false);
prevBtn.addMouseListener(this);
prevBtn.addActionListener(this);
buttonedPanel.add(prevBtn);
}
{
nextBtn = new JButton(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_rest.png")));
nextBtn.setPreferredSize(new java.awt.Dimension(20, 19));
nextBtn.setBackground(getBackground());
nextBtn.setBorderPainted(false);
nextBtn.addMouseListener(this);
nextBtn.addActionListener(this);
}
{
clockFaceCount = new JTextField();
clockFaceCount.setPreferredSize(new java.awt.Dimension(50, 19));
clockFaceCount.setBackground(getBackground());
clockFaceCount.setBorder(null);
clockFaceCount.setHorizontalAlignment(SwingConstants.CENTER);
clockFaceCount.setEditable(false);
buttonedPanel.add(clockFaceCount);
buttonedPanel.add(nextBtn);
}
{
clockFace = new String[]{"http://imgur.com/079QSdJ","http://imgur.com/vQ7tZjI",
"http://imgur.com/T8x0I29"};
for(int i = 1; i <= clockFace.length; i++){
if(i == 1){
nextBtn.setEnabled(true);
prevBtn.setEnabled(false);
}
clockFaceCount.setText(arrayPointer+" of "+clockFace.length);
}
}
{
leftPanel = new JPanel();
leftPanel.setPreferredSize(new Dimension(40, getHeight()));
add(leftPanel,BorderLayout.WEST);
}
{
rightPanel = new JPanel();
rightPanel.setPreferredSize(new Dimension(40,getHeight()));
add(rightPanel,BorderLayout.EAST);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void mouseClicked(MouseEvent me) {
if(me.getSource() == prevBtn)
prevBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_pressed.png")));
else
nextBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_pressed.png")));
}
#Override
public void mouseEntered(MouseEvent me) {
if(me.getSource()==prevBtn)
prevBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_hover.png")));
else
nextBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_hover.png")));
}
#Override
public void mouseExited(MouseEvent me) {
if(me.getSource() == prevBtn)
prevBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_rest.png")));
else
nextBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_rest.png")));
}
#Override
public void mousePressed(MouseEvent me) {
if(me.getSource() == prevBtn){
prevBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_pressed.png")));
}else{
nextBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_pressed.png")));
}
}
#Override
public void mouseReleased(MouseEvent me) {
if(me.getSource() == prevBtn)
prevBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_hover.png")));
else
nextBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_hover.png")));
}
#Override
public void actionPerformed(ActionEvent ae) {
if(ae.getSource() == nextBtn){
{
if(arrayPointer < clockFace.length){
++arrayPointer;
prevBtn.setEnabled(true);
if(arrayPointer == clockFace.length)
nextBtn.setEnabled(false);
}
clockFaceCount.setText(arrayPointer + " of " + clockFace.length);
setAnalogClockFace(arrayPointer);
}
}else if(ae.getSource() == prevBtn){
{
if(arrayPointer > 1){
--arrayPointer;
nextBtn.setEnabled(true);
if(arrayPointer == 1){
clockFaceCount.setText(arrayPointer+" of "+clockFace.length);
prevBtn.setEnabled(false);
}
}
clockFaceCount.setText(arrayPointer + " of "+clockFace.length);
setAnalogClockFace(arrayPointer);
}
}
}
private void setAnalogClockFace(int pointerPosition) {
try{
image = ImageIO.read(getClass().getClassLoader().getResource(clockFace[pointerPosition]));
}catch(IOException io){
io.printStackTrace();
}
}
public BufferedImage getAnalogClockFace(){
return image;
}
}
I've been working on this for days, can someone please help me understand what am not doing right? Any help would be greatly appreciated.
Here is an MCVE using a JLabel to achieve the same result:
package panels;
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.event.*;
import java.awt.BorderLayout;
#SuppressWarnings({"serial"})
public class ClockPanel extends javax.swing.JPanel implements ActionListener {
private JLabel clockImageLabel;
private JPanel buttonsPanel;
private JButton next,prev;
private JTextField displayCount;
String[] imageFaces;
int pointer = 1;
/**
* Auto-generated main method to display this
* JPanel inside a new JFrame.
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new ClockPanel());
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public ClockPanel() {
super();
initGUI();
}
private void initGUI() {
try {
setPreferredSize(new Dimension(203, 237));
BorderLayout panelLayout = new BorderLayout();
setLayout(panelLayout);
{
clockImageLabel = new JLabel();
clockImageLabel.setPreferredSize(new Dimension(203,203));
clockImageLabel.setHorizontalAlignment(SwingConstants.CENTER);
clockImageLabel.setVerticalAlignment(SwingConstants.CENTER);
add(clockImageLabel,BorderLayout.NORTH);
}
{
buttonsPanel = new JPanel();
{
next = new JButton(">");
next.addActionListener(this);
}
{
prev = new JButton("<");
prev.addActionListener(this);
displayCount = new JTextField();
displayCount.setBorder(null);
displayCount.setEditable(false);
displayCount.setBackground(getBackground());
displayCount.setHorizontalAlignment(SwingConstants.CENTER);
buttonsPanel.add(prev);
buttonsPanel.add(displayCount);
displayCount.setPreferredSize(new java.awt.Dimension(45, 23));
buttonsPanel.add(next);
add(buttonsPanel,BorderLayout.SOUTH);
}
{
imageFaces = new String[]{"http://imgur.com/T8x0I29",
"http://imgur.com/079QSdJ","http://imgur.com/vQ7tZjI"
};
for(int i = 1; i < imageFaces.length; i++){
if(i == 1){
next.setEnabled(true);
prev.setEnabled(false);
}
displayCount.setText(pointer+" of "+imageFaces.length);
setLabelImage(pointer);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void setLabelImage(int pointerPosition){
clockImageLabel.setIcon(new ImageIcon(getClass().getClassLoader().getResource(imageFaces[pointerPosition])));
this.repaint();
}
#Override
public void actionPerformed(ActionEvent ae) {
if(ae.getSource() == next){
if(pointer < imageFaces.length){
++pointer;
prev.setEnabled(true);
if(pointer == imageFaces.length)next.setEnabled(false);
displayCount.setText(pointer+" of "+imageFaces.length);
setLabelImage(pointer);
}
}else if(ae.getSource() == prev){
if(pointer > 1){
--pointer;
next.setEnabled(true);
if(pointer == 1)prev.setEnabled(false);
displayCount.setText(pointer+" of "+imageFaces.length);
setLabelImage(pointer);
}
}
}
}
Here are 1/2 Images for the code:
HandlessAnalogClock 1
HandlessAnalogClock 2
HandlessAnalogClock 3
This MCVE will successfully flip between two of the three images, but still has problems with ArrayIndexOutOfBoundsException.
That last part is 'Batteries Not Included' (left as an exercise for the user to correct).
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.net.URL;
#SuppressWarnings({"serial"})
public class ClockPanel extends JPanel implements ActionListener {
private JLabel clockImageLabel;
private JPanel buttonsPanel;
private JButton next, prev;
private JTextField displayCount;
BufferedImage[] images;
int pointer = 1;
/**
* Auto-generated main method to display this JPanel inside a new JFrame.
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new ClockPanel());
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
public ClockPanel() {
super();
initGUI();
}
private void initGUI() {
try {
setPreferredSize(new Dimension(203, 237));
BorderLayout panelLayout = new BorderLayout();
setLayout(panelLayout);
clockImageLabel = new JLabel();
clockImageLabel.setPreferredSize(new Dimension(203, 203));
clockImageLabel.setHorizontalAlignment(SwingConstants.CENTER);
clockImageLabel.setVerticalAlignment(SwingConstants.CENTER);
add(clockImageLabel, BorderLayout.NORTH);
buttonsPanel = new JPanel();
next = new JButton(">");
next.addActionListener(this);
prev = new JButton("<");
prev.addActionListener(this);
displayCount = new JTextField();
displayCount.setBorder(null);
displayCount.setEditable(false);
displayCount.setBackground(getBackground());
displayCount.setHorizontalAlignment(SwingConstants.CENTER);
buttonsPanel.add(prev);
buttonsPanel.add(displayCount);
displayCount.setPreferredSize(new java.awt.Dimension(45, 23));
buttonsPanel.add(next);
add(buttonsPanel, BorderLayout.SOUTH);
String[] imageFaces = new String[]{
"http://i.imgur.com/T8x0I29.png",
"http://i.imgur.com/079QSdJ.png",
"http://i.imgur.com/vQ7tZjI.png"
};
images = new BufferedImage[imageFaces.length];
for (int ii=0; ii<imageFaces.length; ii++) {
System.out.println("loading image: " + ii);
images[ii] = ImageIO.read(new URL(imageFaces[ii]));
System.out.println("loaded image: " + images[ii]);
}
setLabelImage(0);
} catch (Exception e) {
e.printStackTrace();
}
}
private void setLabelImage(int pointerPosition) {
System.out.println("setLabelImage: " + pointerPosition);
clockImageLabel.setIcon(new ImageIcon(images[pointerPosition]));
this.repaint();
}
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == next) {
if (pointer < images.length) {
++pointer;
prev.setEnabled(true);
if (pointer == images.length) {
next.setEnabled(false);
}
displayCount.setText(pointer + " of " + images.length);
setLabelImage(pointer);
}
} else if (ae.getSource() == prev) {
if (pointer > 1) {
--pointer;
next.setEnabled(true);
if (pointer == 1) {
prev.setEnabled(false);
}
displayCount.setText(pointer + " of " + images.length);
setLabelImage(pointer);
}
}
}
}
Expanding on #Andrew's example, consider arranging for the index of the current image to wrap-around, as shown in the example cited here.
private int pointer = 0;
...
private void initGUI() {
...
setLabelImage(pointer);
...
}
private void setLabelImage(int pointerPosition) {
System.out.println("setLabelImage: " + pointerPosition);
clockImageLabel.setIcon(new ImageIcon(images[pointerPosition]));
displayCount.setText((pointerPosition + 1) + " of " + images.length);
this.repaint();
}
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == next) {
pointer++;
if (pointer >= images.length) {
pointer = 0;
}
} else if (ae.getSource() == prev) {
pointer--;
if (pointer < 0) {
pointer = images.length - 1;
}
}
setLabelImage(pointer);
}
As an exercise, try to factor out the repeated instantiation of ImageIcon in setLabelImage() by creating a List<ImageIcon> in initGUI().

Hiding and showing Panel during runtime

I'm trying to show and hide a panel during run time, so I call the methods from another class:
Con.Action(1);
to this method:
public void Action(int whichPanel) {
if (whichPanel == 1) {
if (frame.Data.isVisible()) {
frame.Data.setVisible(false);
// frame.splitPaneSec.remove(frame.Data);
} else {
System.out.println(".....");
//frame.Data.setVisible(false);
frame.Data.setVisible(true);
//frame.getContentPane().validate();
//frame.revalidate();
//frame.repaint();
//frame.pack();
}
}
So far i'm able to hide a panel but I can't show it again once I hidden it.
I've tried many ways some of them are commented out.
Any help is appreciated, cheers
I think I would rather remove and add it back.
parent.remove(dataPanel);
parent.validate();
parent.repaint();
parent.add(dataPanel);
parent.validate();
parent.repaint();
I highly recommed you to use enums for Tasks like this:
public void Action(int whichPanel) {
if (whichPanel == 1) {}
//Better;
public void Action(enumType myPanel){
if(myPanel == enumType.LoginScreen){}
with `
public enum enumType
{
LoginScreen,EditScreen //...
}`
You can hide and show Enums if you perfom the setVisible method directly on the Panel you want to show:
public void showLoginScreen()
{
loginPanel.setVisible(true);
registerMenu.setVisible(false);
}
The issue was because after setting the component back to visible
it was required to GUIClass.splitPane.setDividerLocation(157);
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
public class HidePanel extends JFrame {
private static final int PANEL_HEIGHT = 50;
private static final int INITIAL_PANEL_WIDTH = 50;
private static final int TIMER_INTERVAL = 1;
private static final int PIXEL_DELTA = 2;
private Dimension panelDimension = new Dimension(INITIAL_PANEL_WIDTH, PANEL_HEIGHT);
private int vertOffset = -PANEL_HEIGHT;
private Timer showTimer = new HidePanel.ShowPanelTimer();
private Timer hideTimer = new HidePanel.HidePanelTimer();
static JLayeredPane lpane = new JLayeredPane();
JPanel panel = new JPanel();
public HidePanel() {
setBackground(Color.BLACK);
setLayout(null);
panel.setBounds(1200, 50, 100, 600);
panel.setBorder(new TitledBorder(new EtchedBorder(), "Hide"));
panel.add(new JButton("Click Me"));
lpane.add(panel);//, //new Integer(0), 0);
add(panel);
addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
final int height = e.getY() - 100 ;
if (height < 50 && !showTimer.isRunning() && !panel.isVisible()) {
showTimer.start();
} else if (height > PANEL_HEIGHT + 5 && !hideTimer.isRunning() && panel.isVisible()) {
hideTimer.start();
}
}
});
}
public static void main(String args[]) {
HidePanel h = new HidePanel();
h.setSize(1350, 700);
h.setVisible(true);
h.add(lpane, BorderLayout.CENTER);
}
private void positionPanel(final int offset) {
int panelWidth = getWidth();
System.out.println(" offset = " + offset);
panelDimension.setSize(panelWidth, PANEL_HEIGHT);
//panel.setBounds(insets.left, offset + insets.top, size.width, size.height);
}
private class ShowPanelTimer extends Timer implements ActionListener {
ShowPanelTimer() {
super(TIMER_INTERVAL, null);
addActionListener(this);
}
public void start() {
vertOffset = -PANEL_HEIGHT;
panel.setVisible(true);
super.start();
}
public void actionPerformed(ActionEvent e) {
if (vertOffset <= 0) {
positionPanel(vertOffset);
} else {
showTimer.stop();
}
vertOffset += PIXEL_DELTA;
}
}
private class HidePanelTimer extends Timer implements ActionListener {
HidePanelTimer() {
super(TIMER_INTERVAL, null);
addActionListener(this);
}
public void stop() {
panel.setVisible(false);
super.stop();
}
public void actionPerformed(ActionEvent e) {
if (vertOffset >= (-PANEL_HEIGHT)) {
vertOffset -= PIXEL_DELTA;
positionPanel(vertOffset);
} else {
hideTimer.stop();
}
}
}
}

Categories