JButton disappears when resize - java

anyone know or have an idea as to why my button disappears after i resize the applet?
this is my code:
import java.awt.event.*;
import javax.swing.*;
import acm.program.*;
public class button extends ConsoleProgram {
public void init(){
hiButton = new JButton("hi");
add(hiButton, SOUTH);
addActionListeners();
}
public void actionPerformed(ActionEvent e){
if(hiButton == e.getSource()){
println("hello") ;
}
}
private JButton hiButton;
}

I'm not sure if it is a good Idea to redefine the init-method. When I have a look at http://jtf.acm.org/javadoc/student/acm/program/ConsoleProgram.html I would expect that you have implement only the run-method. Overriding init without calling super.init() Looks strange to me.
Maybe I would be better to derive from JApplet directly for your first steps in Applet programming.

Assuming that
your ConsoleProgram extends (directly or indirectly) JApplet
You declared SOUTH as a static final variable that has the value BorderLayout.SOUTH (otherwise your code doesn't compile)
The code should work, no need to repaint (unless you would like to do some application-specific optimization). I just copied and pasted your code (by expliciting the two assumptions above), I see the applet and the button doesn't disappear on resize.
Anyway there are few "not good" things in the code:
First of all, a naming convention issue: the class name should be "Button" with the first letter capitalized (on top of that, it's a poor name for an Applet)
Second, action listeners should be attached before adding the component;
Third, as Oracle doc suggests here, the code that builds the GUI should be a job that runs on the event dispatcher thread. You can do that by wrapping the build gui code in a Runnable using a SwingUtilities.invokeAndWait(Runnable()

Have you tried calling super.init() at the start of your init() method?

Try explicitly using a layout for your Console and then use relative positioning.

To re-size a button in Applet:
public class Button extends JApplet implements ActionListener {
private JButton button;
public void init() {
Container container = getContentPane();
container.setLayout(null);
container.setBackground(Color.white);
button = new JButton("Press Me");
button.setSize(getWidth()/2,20);
button.setLocation(getWidth()/2-button.getSize().width/2, getHeight()/2-button.getSize().height/2);
container.add(button);
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
int width = (button.getSize().width == getWidth()/2) ? getWidth()/4 : getWidth()/2;
int height = button.getSize().height;
button.setSize(width,height);
button.setLocation(getWidth()/2-width/2, getHeight()/2-height/2);
}
}
To re-size a button in JFrame:
public class Button extends JFrame implements ActionListener {
private JButton button;
public Button(String title) {
Container container = getContentPane();
container.setLayout(null);
container.setBackground(Color.white);
setTitle(title);
setSize(400,400);
button = new JButton("Press Me");
button.setSize(getWidth()/2,20);
button.setLocation(getWidth()/2-button.getSize().width/2,
getHeight()/2-button.getSize().height/2);
container.add(button);
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
int width = (button.getSize().width == getWidth()/2) ? getWidth()/4 : getWidth()/2;
int height = button.getSize().height;
button.setSize(width,height);
button.setLocation(getWidth()/2-width/2, getHeight()/2-height/2);
}
public static void main(String[] args) {
Button button = new Button("Test");
button.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.setVisible(true);
}
}

Have you declared the repaint method...???
You are using swing. It needs to have declared a repaint.
Please define a custom repaint mwthod

Related

Can I change an unique MouseListener methods with several JButton in JAVA?

Goal
What I want to do is to set a MouseListener on a Panel when click on a Button1.
Then I want to click on another Button that changes the MouseListener code to do something else.
Example of application
Click on JButton1 -> add MouseListener that change a JLabel background color to red.
Click on JButton2 -> DOESNT ADD a new MouseListener, but change the first one to set the JLabel text to "hello world"
What I can't do
I don't know how to modify an UNIQUE MouseListener.
What I tried
I tried to set an jButton.actionPerformed( new jLabel1.addMouseListener()) for each button, but they create two instance of MouseListener.
I don't want to set one MouseListener for several JButtons, but several JButton changing the status of my MouseListener.
Thanks alot :)
Better to give the JLabel a MouseListener from the get-go, but give it boolean if-blocks that will turn on or off functionality depending on the state of class boolean fields. In your button ActionListeners, simply change the state of these boolean fields. For example in the code below, the boolean flag labelListenerOn is toggled on or off in the first JButton's ActionListener. The JLabel's MouseListener checks the state of this variable and changes the labels background color if the flag is true only. Similarly for the other boolean flag and other ActionListener:
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class ButtonListener extends JPanel {
private static final String TURN_ON_MOUSE = "Turn On Mouse";
private static final String TURN_OFF_MOUSE = "Turn Off Mouse";
private JButton button1 = new JButton(TURN_ON_MOUSE);
private JButton button2 = new JButton("Button 2");
private JLabel label1 = new JLabel("Label 1");
private MouseListener labelListener = new LabelListener();
private boolean labelListenerOn = false;
private boolean labelChangeText = false;
public ButtonListener() {
label1.setOpaque(true);
label1.addMouseListener(labelListener);
button1.addActionListener(e -> {
if (labelListenerOn) {
labelListenerOn = false;
((JButton) e.getSource()).setText(TURN_ON_MOUSE);
} else {
labelListenerOn = true;
((JButton) e.getSource()).setText(TURN_OFF_MOUSE);
}
});
button2.addActionListener(e -> {
labelChangeText = true;
});
add(button1);
add(button2);
add(label1);
}
private class LabelListener extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
Color labelColor = label1.getBackground();
if (labelListenerOn) {
if (labelColor.equals(Color.RED)) {
label1.setBackground(null);
} else {
label1.setBackground(Color.RED);
}
// label1.repaint(); // per Rob Camick's comment, this is not necessary
}
if (labelChangeText) {
label1.setText("Hello World");
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
ButtonListener mainPanel = new ButtonListener();
JFrame frame = new JFrame("ButtonListener");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
If you want to get fancy, look up M-V-C for "model-view-controller", where you separate the program logic (here the state of the boolean flags) from the program view code (the Swing GUI code), usually in their own classes, and then use a master class to hook all the components up. This would add an additional layer of indirection and complexity, and would be over-kill in this situation, but in large programs, and especially in programs that are likely going to be updated, changed and grown, this will actually reduce complexity in the long run, and make the program much more "scalable" -- easier to grow and modify. Again, I do not recommend that you do this here, but do look it over for possible future use.

How to update components listening a button in java

I am a bit sorry to ask this question, since it seems to be a bit obvious, but I can't find my solution alone.
I am coding a little app in Java, and I encounter some issues "redrawing" my swing components. Basically, I want my JFrame to update when an event occurs. I managed to reproduced the issue in the code below. This code is supposed to display two buttons (which it does), and replace them with a third button when you click on the first button (which it doesn't).
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JFrame implements ActionListener {
private JButton button = new JButton("Button 1");
private JButton button2 = new JButton("Button 2");
private JButton button3 = new JButton("Button 3");
private JPanel buttons = new JPanel();
public void init() {
this.setVisible(true);
this.setSize(500,500);
buttons.add(button);
buttons.add(button2);
this.add(buttons);
this.button.addActionListener(this);
}
public void update() {
this.removeAll();
buttons.add(button3);
this.revalidate();
}
public static void main(String[] args) {
Example ex = new Example();
ex.init();
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button) {
update();
}
}
}
I am pretty sure that I am doing something wrong in the update() method. I actually have a lot of trouble to understand how works removeAll(), revalidate(), repaint() etc, and I guess that is the problem. I tried to call the same methods on the buttons panel, it almost worked but I still have a graphic bug, and I would like to do it for all the container. I also tried to call these methods on this.getContentPane(), but it doesn't work.
Can anyone try to help me with it?
You're removing all components from this (which in this case is the JFrame (as you're extending it, which isn't needed, and instead you should create an instance from it rather than inherit from it, as you're not changing the behavior of the JFrame so it's better to just create an instance of it). See: Extends JFrame vs. creating it inside the program
In this case you're adding your components in this way:
JFrame > buttons (JPanel) > JButtons
And you're trying to remove
JFrame > everything
That includes the contentPane, instead you should call.
buttons.removeAll()
Inside the update() method.
And also call this.repaint() so your update() method should become:
public void update() {
buttons.removeAll();
buttons.add(button3);
this.revalidate();
this.repaint();
}
Or the best approach is to use CardLayout as recommended by #AndrewThompson in the comment below. This way you don't have to handle removing / repainting for each component, as CardLayout will do it for you. For example
this works,
public void update() {
buttons.remove(button);
buttons.remove(button2);
buttons.add(button3);
this.revalidate();
this.repaint();
}

How to check JToggleButton state in a class from another class using IF-statement that have actionPerformed within it?

EDIT : I found my problem but still don't have a clue for why this happen, I'm still not finished Online Lectures from Professor Mehran
Sahami (Stanford), maybe I'll find an answer if I push on on the
lecture videos.
The problem is I remove my other components methods before my button
method for efficient posting space, so I should put my JToggleButton
method after my main JFrame method for it to work, but what if my
other components inherit other class too? Which method should I put first to make all of components works? That I'll found out with
practicing java more.
Thank you #Dan and #SebVb for answers and suggestions, sorry if this
just a beginners mistake :)
I am learning java for a month now and already had simple project for learning but now I have problems with JToggleButton, ItemEvent, and actionPerformed included in If-statement.
I've searching for a week for examples on using actionPerformed within if-statement that have ItemEvent from another class but i can't find a same problem to produce a working result.
I'm trying to make a window scanner that will scan only if toggle button is selected then paint JPanel using buffered image (repaint every 100 millisecond) and disposed it if toggle button is deselected, but I think my approach to do it is wrong. I have one main class and two sub-classes like these:
Main class:
public class WindowScanner {
public static void main(String[] args) {
new Window().setVisible(true);
}
}
Window class:
class Window extends JFrame {
static JToggleButton captureButton = new JToggleButton("CAPTURE");
#SuppressWarnings("Convert2Lambda")
public Window() {
// JFrame looks codes
/** EDIT: these components method should be written after button method
* JPanel looks codes
* JLabel looks codes
* END EDIT
*/
add(captureButton);
// capture button default looks code
ItemListener captureListener = new ItemListener(){
#Override
public void itemStateChanged(ItemEvent captureButtonEvent) {
int captureState = captureButtonEvent.getStateChange();
if(captureState == ItemEvent.SELECTED){
// capture button SELECTED looks code
System.out.println("capture button is selected");
} else if(captureState == ItemEvent.DESELECTED){
// capture button DESELECTED looks code
System.out.println("capture button is deselected");
}
}
}; captureButton.addItemListener(captureListener);
}
}
Scanner class:
public class Scanner extends Window {
private static BufferedImage boardCaptured;
static int delay = 100;
protected BufferedImage boardScanned(){
return boardCaptured;
}
#SuppressWarnings("Convert2Lambda")
public static void Scan() {
if (captureButton.isSelected()) {
ActionListener taskPerformer = new ActionListener() {
#Override
public void actionPerformed(ActionEvent captureEvent) {
try {
// capturing method
} catch (AWTException error) {
// AWTException error method
}
// is this the right place to put JPanel code?
JPanel panel = new JPanel();
boardCaptured = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphic = boardCaptured.createGraphics();
panel.setSize(500,500);
panel.paint(graphic);
panel.revalidate();
panel.repaint();
}
}; new Timer(delay, taskPerformer).start();
} else {
// this suppose to end capturing if capture button isSelected() == false
}
}
}
So here is my questions:
Do I really have to make Main class separated from Window class?
What the reason?
How to make my if statement in Scan method recognize state of my
JToggleButton from Window class? Is it impossible and I had a wrong
approach to do it?
In Scanner class, i can't make a get/set for my actionPerformed
(Netbeans always checked it as an error), but why I can make one for
BufferdImage?
If I can't get question number 3 happen, how can I make If statement
to stop capturing using Timer.stop()? Or am I in wrong approach again?
Do my JPanel in Scanner class would be produced and make a viewer
for my buffered image?
P.S. I'm sorry it cramped with questions, I tried not to make multiple post, so I make single post with multiple questions. Please notice me if there's answer before, I'm honestly can't find it or had search it with wrong tags.
Here is a simple version of what I think you want to do. This can be edited to include your variables, such as boardCaptured. This code mainly portrays how to get a component from a different class.
Main.java (Contains all the classes in one java file)
import javax.swing.JLabel;
import javax.swing.JToggleButton;
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.Timer;
class WindowScanner extends JFrame {
private JLabel label;
private JToggleButton captureButton = new JToggleButton("CAPTURE");
WindowScanner() {
super("Fist Window");
setSize(150, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
add(captureButton);
setVisible(true);
new Scanner(this);
}
public JToggleButton getCaptureButton() {
return captureButton;
}
}
class Scanner extends JFrame {
private WindowScanner wS;
private int delay = 1000;
private Timer t = new Timer(delay, new taskPerformer());
Scanner(WindowScanner wS) {
super("Second Window");
this.wS = wS;
setBounds(200,0,500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
wS.getCaptureButton().addActionListener(new taskPerformer());
}
private Color randomColor() {
Random rand = new Random();
float r = rand.nextFloat() / 2f ;
float g = rand.nextFloat() / 2f;
float b = rand.nextFloat() / 2f;
Color randomColor = new Color(r, g, b);
return randomColor;
}
private class taskPerformer implements ActionListener {
#Override
public void actionPerformed(ActionEvent captureEvent) {
if(captureEvent.getSource() == wS.getCaptureButton()) {
if (wS.getCaptureButton().isSelected()) {
t.start();
} else {
t.stop();
}
}
if(captureEvent.getSource() == t) {
getContentPane().setBackground(randomColor());
revalidate();
repaint();
}
}
}
}
public class Main {
public static void main (String[] args) {
new WindowScanner();
}
}
This particular piece of code changes the color of the background in the second JFrame to a random color every second using a timer from javax.swing.timer. This code portrays how to get a component, or a variable if you change it, from a different class.
It is mainly these code fragments which allow it.
1
public JToggleButton getCaptureButton() {
return captureButton;
}
This allows other classes to get the component.
2
private WindowScanner wS;
Scanner(WindowScanner wS) {
...
this.wS = wS;
...
}
This makes the current instance of WindowScanner and the instance of WindowScanner declared in Scanner the same instance.
Note: Look into using public getters and setters.
As for your 5 listed questions.
1) Do I really have to make Main class separated from Window class? What the reason?
In most cases yes you do. As SebVb said it is good practice. However you can do something like this if you wish to have them in the same class.
import javax.swing.JToggleButton;
import javax.swing.JFrame;
import java.awt.FlowLayout;
public class Test extends JFrame {
private JToggleButton captureButton = new JToggleButton("CAPTURE");
Test() {
super("Fist Window");
setSize(150, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
add(captureButton);
setVisible(true);
}
public JToggleButton getCaptureButton() {
return captureButton;
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Test frame = new Test();
}
});
}
}
2) How to make my if statement in Scan method recognize state of my JToggleButton from Window class? Is it impossible and I had a wrong approach to do it?
You were using the wrong approach to do this. See the code and code fragments I have put above for how to do it correctly. (Using public getters.)
3) In Scanner class, i can't make a get/set for my actionPerformed (Netbeans always checked it as an error), but why I can make one for BufferdImage?
I can't entirely say I'm sure what you are asking but see my code above to see if that helps. If it doesn't leave a comment trying to fully explain what you mean.
4) If I can't get question number 3 happen, how can I make If statement to stop capturing using Timer.stop()? Or am I in wrong approach again?
In my code I show you how this can be related to the JToggleButton. See code fragment below
private class taskPerformer implements ActionListener {
#Override
public void actionPerformed(ActionEvent captureEvent) {
if(captureEvent.getSource() == wS.getCaptureButton()) {
if (wS.getCaptureButton().isSelected()) {
t.start();
} else {
t.stop();
}
}
if(captureEvent.getSource() == t) {
getContentPane().setBackground(randomColor());
revalidate();
repaint();
}
}
}
This code says when the JToggleButton fires an ActionEvent if it is selected then start the timer, t.start(), or if it is not selected stop the timer, t.stop().
5) Do my JPanel in Scanner class would be produced and make a viewer for my buffered image?
Again I'm not entirely sure what you are asking but here is my best guess. You have two options.
1
Put boardCaptured directly on the frame.
paint(graphic);
repaint();
revaildate();
2
Create a JPanel like you did but outside the ActionListener
JPanel panel = new JPanel()
boardCaptured = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphic = boardCaptured.createGraphics();
panel.setSize(500,500);
panel.paint(graphic);
add(panel);
private class taskPerformer implements ActionListener {
if(captureEvent.getSource() == t) {
panel.paint(graphic);
panel.revalidate();
panel.repaint();
}
}
I think there's an easier way do do what do you want. Taking your questions by order
Having the main class separated from your Window class allow you to re-use your Windows class everywhere you want. It's a good pratice to only init your GUI objects on your main class
Why don't you have your JToggleButton private and a mehtod wwhich will access to his status ? also, with a static field, all your instaces of Windows will share the same JToggleButton.
It's an anonymous class that contains your actionPerformed method. If you want to see it, you have to create an inner class.
I think your approch is wrong. Using a thread, which will launch your repaint with a specific delay is better. If you create a class which extends Runnable, you can check the state of your button and then do the appropriate action
Your JPanel is inside an ActionListener, i've never seen that and i don't think that it can works.
In a shorter version
Put in your Window class your JPanel, BufferedImage and JToggleButton
Create a specific thread to do your repainting when the JToggleButton is selected

Text Box not working properly

I wrote a program for an applet that is supposed to display different text in a text box when you push a button. My program has no errors when I compiled it, but the text box doesn't display correctly. I don't know what is wrong with it. Here is my code
import java.awt.*;
import java.awt.event.*;
public class colors{
Button button1;
Button button2;
Button button3;
Label label1;
TextField objTextField1;
public static void main (String args[]){
colors c = new colors();
}
public colors() {
Frame f = new Frame ("Colors");
Button button1 = new Button("Blue");
button1.setBounds(10,305,120,75);
button1.addMouseListener(new MyMouseListener1());
Button button2 = new Button("Red");
button2.setBounds(140,305,120,75);
button2.addMouseListener(new MyMouseListener2());
Button button3 = new Button("Yellow");
button3.setBounds(270,305,120,75);
button3.addMouseListener(new MyMouseListener3());
f.add(button1);
f.add(button2);
f.add(button3);
label1 = new Label("Click a Button to Reveal Text");
label1.setBounds(20,105,200,25);
f.add(label1);
objTextField1 = new TextField("Which Color?", 15);
objTextField1.setBounds(20,75,125,50);
f.add(objTextField1);
f.add(label1);
f.add(objTextField1);
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent we){
System.exit(0);
}
});
f.setSize(400,400);
f.setVisible(true);
}
public class MyMouseListener1 extends MouseAdapter{
public void mouseClicked(MouseEvent me){
objTextField1.setText("Blue");
}
}
public class MyMouseListener2 extends MouseAdapter{
public void mouseClicked(MouseEvent me){
objTextField1.setText("Red");
}
}
public class MyMouseListener3 extends MouseAdapter{
public void mouseClicked(MouseEvent me){
objTextField1.setText("Yellow");
}
}
}
When a Button is clicked it fires an ActionEvent.
You should use an ActionListener instead of a MouseListener.
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...
}
AND don't forget to add
button.addActionListener(instance);
I have tested your code and it's working as expected but I have noticed some of the points in your code as mentioned below:
Use setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) instead of System.exit(0) and adding WindowListener to close the window.
Use frame.pack() instead of frame.setSize() that fits the components as per component's preferred size.
Don't use null layout and never use absolute positioning via calling setBounds() instead use a proper Layout Manager that suits as per your application design.
Read more How to Use Various Layout Managers
Use SwingUtilities.invokeLater() or EventQueue.invokeLater() to make sure that EDT is initialized properly.
Read more
Why to use SwingUtilities.invokeLater in main method?
SwingUtilities.invokeLater
Should we use EventQueue.invokeLater for any GUI update in a Java desktop application?
Follow Java Naming convention
Keep the instance members private
This is already addressed by #TAsk that you should be using ActionListener instead of MouseListener if you are interested in only mouseClicked() method.
You should be using Swing components instead of AWT components as already mentioned by #peeskillet
To make an applet you should extend javax.swing.JApplet class & override init() method.
To change the color, you must write your logics in actionPerformed() of ActionListener. But it's an interface. So, you can make use of Anonymous Inner class & implement actionPerformed() in it.
So, when you call addActionListener() on a JButton, I recommend you to do that by using Anonymous Inner class. It would be more clear through following code.
My Suggestion: Whenever you write code, always keep OOD principles in your mind. This isn't right place to discuss that, but your code has a Code smell which is Duplication in code.
Below is the best way to do what you want & we're also using DRY Principle.
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class ColorChanger extends javax.swing.JApplet {
private JPanel mainPanel;
private JButton btnRed;
private JButton btnGreen;
private JButton btnBlue;
#Override
public void init() {
super.init();
mainPanel = new JPanel();
btnRed = new JButton("Red");
btnGreen = new JButton("Green");
btnBlue = new JButton("Blue");
this.add(mainPanel);
mainPanel.add(btnRed);
mainPanel.add(btnGreen);
mainPanel.add(btnBlue);
bindActionEvent(btnRed, Color.RED);
bindActionEvent(btnGreen, Color.GREEN);
bindActionEvent(btnBlue, Color.BLUE);
}
private void bindActionEvent(JButton b1, Color color) {
b1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mainPanel.setBackground(color);
//Write setText() for your TextField here.
}
});
} //END Of Helper Method
}

How to make an image gallery with java

For class I'm working on my first GUI application. It's just a simple image viewer with four buttons: Previous, Next, Stop, Play. Previous and Next work fine, but honestly I don't even know how to begin working on the slideshow part (Play & Stop). I know there's a timer class that would probably be handy for controlling the speed as the images change...but I'm not sure what kind of logic is typically used to cycle through the images. Can anyone point me in the right direction, my brain is a little fried at this point :0
I've included my code below. I'm new to this, so hopefully people won't be too critical of my technique. If it matters, I'm working in eclipse.
here's my code so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.TimerTask;
public class ImageGallery extends JFrame
{
private ImageIcon myImage1 = new ImageIcon ("Chrysanthemum.jpg");
private ImageIcon myImage2 = new ImageIcon ("Desert.jpg");
private ImageIcon myImage3 = new ImageIcon ("Jellyfish.jpg");
private ImageIcon myImage4 = new ImageIcon ("Penguins.jpg");
JPanel ImageGallery = new JPanel();
private ImageIcon[] myImages = new ImageIcon[4];
private int curImageIndex=0;
public ImageGallery ()
{
ImageGallery.add(new JLabel (myImage1));
myImages[0]=myImage1;
myImages[1]=myImage2;
myImages[2]=myImage3;
myImages[3]=myImage4;
add(ImageGallery, BorderLayout.NORTH);
JButton PREVIOUS = new JButton ("Previous");
JButton PLAY = new JButton ("Play");
JButton STOP = new JButton ("Stop");
JButton NEXT = new JButton ("Next");
JPanel Menu = new JPanel();
Menu.setLayout(new GridLayout(1,4));
Menu.add(PREVIOUS);
Menu.add(PLAY);
Menu.add(STOP);
Menu.add(NEXT);
add(Menu, BorderLayout.SOUTH);
//register listener
PreviousButtonListener PreviousButton = new PreviousButtonListener ();
PlayButtonListener PlayButton = new PlayButtonListener ();
StopButtonListener StopButton = new StopButtonListener ();
NextButtonListener NextButton = new NextButtonListener ();
//add listeners to corresponding componenets
PREVIOUS.addActionListener(PreviousButton);
PLAY.addActionListener(PlayButton);
STOP.addActionListener(StopButton);
NEXT.addActionListener(NextButton);
}
public static void main (String [] args)
{
ImageGallery frame = new ImageGallery();
frame.setSize(490,430);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
}
class PreviousButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(curImageIndex>0 && curImageIndex <= 3)
{ ImageGallery.remove(0);
curImageIndex=curImageIndex-1;
ImageIcon TheImage= myImages[curImageIndex];
ImageGallery.add(new JLabel (TheImage));
ImageGallery.validate();
ImageGallery.repaint();
}
else
{
ImageGallery.remove(0);
ImageGallery.add(new JLabel (myImage1));
curImageIndex=0;
ImageGallery.validate();
ImageGallery.repaint();
}
}
}
class PlayButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
// *need help here*//
}
}
class StopButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
// *need help here*//
}
}
class NextButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(curImageIndex>=0 && curImageIndex < 3)
{ ImageGallery.remove(0);
curImageIndex = curImageIndex + 1;
ImageIcon TheImage= myImages[curImageIndex];
ImageGallery.add(new JLabel (TheImage));
ImageGallery.validate();
ImageGallery.repaint();
}
else
{
ImageGallery.remove(0);
ImageGallery.add(new JLabel (myImage4));
curImageIndex=3;
ImageGallery.validate();
ImageGallery.repaint();
}
}
}
}
Why complicating simple things,
I think that this is job for CardLayout and for slideshow is there Swing Timer
put images as Icon to the JLabel
This example shows a start/stop button that controls a javax.swing.Timer. Instead of replacing the label each time, just update the label's Icon, as suggested by #mKorbel and shown here.
You need use a thread for the slideshow. You can use a flag in the run method for continue with the show or stop if this flag change, for example, a boolean var. One example you can see in http://java.sun.com/developer/technicalArticles/Threads/applet/.
These are some guidelines that might get you started:
First you will need a separate thread to control the changing images. I suggest you write a class that implements TimerTask. Override the run() method in this class. In this run method you should put the functionality to change the current image being displayed (similar to what you did in the next and previous function).
In the actionPerformed() method for the play button you will need to create an instance of a Timer class and start your timer using the scheduleAtFixedRate(TimerTask task, long delay, long period) method (other methods in this class may be used as well, scheduleAtFixedRate() seem more appropriate though).
For the stop you will then need to add enough functionality to stop the running timer using the cancel() method in the Timer class

Categories