Reputation: 43
First off this is a homework assignment so explanations and pointers are preferred over flat solutions. We are learning swing and are practicing separate class ActionListeners (bonus question, why would you use a separate class over an inner class, it seems like inner class is simpler and less error prone without losing any real abilities). The problems I have been running into are passing the Frame as a parameter so that the separate class can access the tools it needs, and then using the separate class to actually change the display. The project is supposed to work something like a slideshow, having a timer as a default switch, but also implementing buttons to move manually.
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.event.*;
import java.io.File;
public class SliderFrame extends JFrame{
public SliderFrame(){
File file1 = new File("images"); //change as necessary
File file = new File("images\\CMU");
File[] paths;
paths = file.listFiles();
//file1
ImageIcon left = new ImageIcon("backward.png");
ImageIcon right = new ImageIcon("forward.png");
JButton btnLeft = new JButton(left);
btnLeft.addActionListener(new MyActionListener(this));
JButton btnRight = new JButton(right);
btnRight.addActionListener(new MyActionListener(this));
JTextField jtfTitle = new JTextField("Welcome to CMU!");
JLabel jlbMain = new JLabel();
new Timer(2000, new MyActionListener(this)).start();
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add("PAGE_START", jtfTitle);
panel.add("Center", jlbMain);
panel.add("LINE_START", btnLeft);
panel.add("LINE_END", btnRight);
add(panel);
setTitle("CPS240 SlideShow");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
JFrame frame = new SliderFrame();
btnRight.addActionListener(new MyActionListener(frame));
}
}
And then my ActionListener Class
import java.awt.event.*;
import javax.swing.*;
//does it need to extend SliderFrame? Originally I thought it would help with some of my errors
public class MyActionListener extends SliderFrame implements ActionListener {
JFrame frame;
public MyActionListener(JFrame frame) {
this.frame = frame;
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() instanceof Timer){
//here's where I need to be able to change the 'main' label in the frame
} else if(e.getSource() == btnRight){
//trying to figure out if the left or right button was pushed
} else{
}
}
}
I'm not sure if the source of my errors lie in how I set up the format to start with or if I'm just not getting something. Any help or opinions would be greatly appreciated.
Upvotes: 2
Views: 1240
Reputation: 347184
bonus question, why would you use a separate class over an inner class, it seems like inner class is simpler and less error prone without losing any real abilities
Initially, you had no choice, as you couldn't have inner classes, but, there may be occasions where the functionality is common and can easily be repeated, for example, an "Open File" action, which is manged by a toolbar button, menu item and keyboard short cut...
First your ActionListener
does not need to extend from SliderFrame
, but instead, probably wants a reference to an instance of SliderFrame
...
This
public class MyActionListener extends SliderFrame implements ActionListener {
Should probably be more like
public class MyActionListener implements ActionListener {
Instead of passing a reference of JFrame
, you will want to pass a reference of SliderFrame
. Having said that, I have no idea where btnRight
is, but I'm pretty sure it shouldn't be maintained within the main
method, but within the SliderFrame
itself...
public class SliderFrame extends JFrame{
public SliderFrame(){
//...
btnRight.addActionListener(new MyActionListener(this));
You ActionListener
should also expect an instance of SliderFrame
public class MyActionListener extends SliderFrame implements ActionListener {
private SliderFrame frame;
public MyActionListener(SliderFrame frame) {
This allows your ActionListener
to make use of functionality that is defined by the SliderFrame
, which won't be available from an instance of JFrame
Next, you want to provide functionality in your SliderFrame
which can be used to update the state of the slide show...
public class SliderFrame extends JFrame{
//...
public void nextSlide() {
//...
}
public void previousSlide() {
//...
}
Then when your ActionListener
is triggered, you just call the appropriate methods on SliderFrame
public class NextSlideActionListener extends SliderFrame implements ActionListener {
//...
@Override
public void actionPerformed(ActionEvent e) {
frame.nextSlide();
}
}
(ps- the above example can be used by the Timer
and "next" button, because the functionality is the same for both)
Upvotes: 2