I have made a program where the right and left arrows show the volume on the JSlider decreasing while the Up and Down arrow show the Channel being changed i.e different colours being shown on screen. I wanted that whenever the screen is stable for 10seconds or more, the "Volume is" and "Channel Is" text along with JSlider should disappear, as it happens in a Television Set. I am using Java Eclipse with VisualSwing as my GUI. My current code is:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import org.dyno.visual.swing.layouts.Constraints;
import org.dyno.visual.swing.layouts.GroupLayout;
import org.dyno.visual.swing.layouts.Leading;
public class TVPanel extends JPanel {
private static JLabel vollab;
private int ChannelNo;
private static final long serialVersionUID = 1L;
private JLabel jLabel0;
private int VolumeMax=10;
private JButton jButton0;
private JSlider jSlider0;
private JMenuItem jMenuItem0;
private JPopupMenu jPopupMenu0;
private JLabel jLabel1;
private static final String PREFERRED_LOOK_AND_FEEL = "javax.swing.plaf.metal.MetalLookAndFeel";
public TVPanel() {
ChannelNo=0;
initComponents();
}
private void initComponents() {
setLayout(new GroupLayout());
add(getJButton0(), new Constraints(new Leading(100, 176, 10, 10), new Leading(39, 72, 10, 10)));
add(getJSlider0(), new Constraints(new Leading(46, 10, 10), new Leading(162, 10, 10)));
add(getJLabel1(), new Constraints(new Leading(111, 10, 10), new Leading(129, 12, 12)));
add(getJLabel0(), new Constraints(new Leading(37, 68, 12, 12), new Leading(129, 12, 12)));
addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent event) {
keyKeyTyped(event);
}
public void keyPressed(KeyEvent event) {
keyKeyPressed(event);
}
});
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent event) {
mouseMouseClicked(event);
}
});
setSize(478, 240);
}
private JLabel getJLabel1() {
if (jLabel1 == null) {
jLabel1 = new JLabel();
jLabel1.setText("10");
}
return jLabel1;
}
private JSlider getJSlider0() {
if (jSlider0 == null) {
jSlider0 = new JSlider();
jSlider0.setMajorTickSpacing(1);
jSlider0.setMaximum(10);
jSlider0.setPaintLabels(true);
jSlider0.setPaintTicks(true);
jSlider0.setValue(10);
jSlider0.setAlignmentX(1.0f);
jSlider0.setInheritsPopupMenu(true);
jSlider0.setValueIsAdjusting(true);
}
return jSlider0;
}
private JButton getJButton0() {
if (jButton0 == null) {
jButton0 = new JButton();
jButton0.setText("");
jButton0.setSize(150, 150);
}
return jButton0;
}
private JLabel getJLabel0() {
if (jLabel0 == null) {
jLabel0 = new JLabel();
jLabel0.setText("Volume Is");
}
return jLabel0;
}
private static void installLnF() {
try {
String lnfClassname = PREFERRED_LOOK_AND_FEEL;
if (lnfClassname == null)
lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();
UIManager.setLookAndFeel(lnfClassname);
} catch (Exception e) {
System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL
+ " on this platform:" + e.getMessage());
}
}
/**
* Main entry of the class.
* Note: This class is only created so that you can easily preview the result at runtime.
* It is not expected to be managed by the designer.
* You can modify it as you like.
*/
public static void main(String[] args) {
installLnF();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("TVPanel");
//JLabel volLab= new JLabel();
vollab= new JLabel("test");
frame.getContentPane().add(vollab);
frame.requestFocus();
frame.isFocusable();
vollab.isVisible();
TVPanel content = new TVPanel();
content.setPreferredSize(content.getSize());
frame.add(content, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
//Arrows
private void keyKeyPressed(KeyEvent event) {
jLabel0.setVisible(true);
jLabel1.setVisible(true);
Color colorarr[]= new Color[] {Color.BLACK,Color.WHITE,Color.BLUE,Color.CYAN,Color.RED,Color.GREEN,Color.GRAY,Color.MAGENTA,Color.ORANGE,Color.YELLOW};
//int Volume=10;
//int ChannelNo=10;
//jLabel0.setText(Integer.toString(event.getKeyCode()));
if(event.getKeyCode()== 37){
VolumeMax--;
jSlider0.setValue(VolumeMax);
jLabel0.setText("Volume Is");
jLabel1.setText(Integer.toString(jSlider0.getValue()));
}
else if(event.getKeyCode()==38)//UP{
{
ChannelNo++;
for(int i=0; i<ChannelNo;i++){
if(i<10){
jButton0.setBackground(colorarr[i]);
jLabel0.setText("Channel Is");
jLabel1.setText(Integer.toString(i+1));
}
}
}
else if(event.getKeyCode()==39){
//RIGHT
VolumeMax++;
jSlider0.setValue(VolumeMax);
jLabel1.setText(Integer.toString(jSlider0.getValue()));
}
else if(event.getKeyCode()==40){
ChannelNo--;
if(ChannelNo>0){
jButton0.setBackground(colorarr[ChannelNo-1]);
jLabel0.setText("Channel Is");
jLabel1.setText(Integer.toString(ChannelNo-1));
}
}
this.requestFocus();
}
private void mouseMouseClicked(MouseEvent event) {
//jLabel0.setText("mouse");
this.requestFocus();
}
//Other keys
private void keyKeyTyped(KeyEvent event) {
if(event.getKeyCode()==37){
//jLabel0.setText("uparrow");
jSlider0.setValue(9);
}
jLabel0.setText("keyType");
this.requestFocus();
}
}
else if(event.getKeyCode()==39){
Never use code with magic numbers. Define static variables if you need to. However, in this case you don't need to since it has already been done for you:
KeyEvent.VK_RIGHT
To have the panel disappear you need to start a Swing Timer to fire in 20 seconds once the panel is displayed. Then whenever a key event or mouse events changes a value on the panel you can restart the Timer.
Read the section from the Swing tutorial on How to Use Timers for more information.
If this is a modal dialog that you are using than maybe you can even use the Application Inacdtivity to help yoo out.
Related
How to move with smooth motion for JPanel and update JLabel at same time?
I want to show current time on a JFrame so I created a new java.util.Timer and update to label every one second.
I created another Java thread to as well, move the panel component.
But while moving the panel and showing (updating) time on the frame, panel refreshing to form original position.
So I search that problem in Google and can't find the solution.
//Code to move jPanel smoothly
Thread t = new Thread(){
int i = 0 ;
public void run(){
while(i<150){
i++;
jPanel2.setLocation(i, jPanel2.getY());
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
}
}
};
t.start();
// Code to show Time
Timer t = new javax.swing.Timer(1, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jLabel1.setText(new Date()+"");
}
});
t.start();
Here is a small example, how to provide animation and update for a component.
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;
/**
* <code>MovedClock</code>.
*/
public class MovedClock {
private final JLabel clock = new JLabel();
private final DateTimeFormatter format = DateTimeFormatter.ofPattern("HH:mm:ss");
private void startUI() {
JFrame frame = new JFrame("Moved clock");
frame.setLayout(null); // usually it's a bad idea, but for animation we need this.
clock.setBounds(0, 50, 50, 20);
frame.add(clock);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(500, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
updateClock();
Timer clockTimer = new Timer(1000, e -> updateClock());
clockTimer.start();
// 15 milliseconds for about 60fps
Timer moveTimer = new Timer(15, new ActionListener() {
private int count = 1;
private int increment = 1;
#Override
public void actionPerformed(ActionEvent e) {
if (count == 435 || count == 0) {
increment = -increment;
}
Point loc = clock.getLocation();
loc.x += increment;
clock.setLocation(loc);
count += increment;
}
});
moveTimer.start();
}
private void updateClock() {
clock.setText(LocalTime.now().format(format));
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new MovedClock()::startUI);
}
}
I'm trying to have a border appear over the react button after the timer has ended. I can't seem to have that happen unless I move the mouse away from the trigger button and then back onto it. Is there a way to activate the mouse listener without moving the mouse off and then back on the trigger button after the timer? And please dont't say: set border when timer ends, because that's not what I'm looking for.
Also, feel free to point out other mistakes or bad habits with my code as well. I'm new to Java coding.
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ButtonTester{
public static final Border PANEL_BORDER = new LineBorder(Color.red, 12);
public static JPanel panel;
public static JButton trigger;
public static JButton react;
public static JLabel msg;
public static void main(String [] args){
JFrame frame = new JFrame();
frame.setSize(new Dimension(500,200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setBorder(PANEL_BORDER);
frame.getContentPane().add(panel);
JButton trigger = new JButton("Trigger");
JButton react = new JButton("React");
JLabel msg = new JLabel();
react.setPreferredSize(new Dimension(200, 60));
trigger.setPreferredSize(new Dimension(200, 60));
panel.add(trigger);
panel.add(react);
panel.add(msg);
panel.setVisible(true);
frame.setVisible(true);
MouseListener mL = new MouseAdapter(){
#Override public void mouseEntered(MouseEvent evt) {
react.setBorder(PANEL_BORDER);
}
#Override public void mouseExited(MouseEvent evt) {
react.setBorder(javax.swing.BorderFactory.createEmptyBorder());
}
};
countDown(msg, trigger, mL);
}
public static void countDown(JLabel msg, JButton trigger, MouseListener mL){
Timer timer = new Timer();
TimerTask task = new TimerTask(){
short seconds = 4;
public void run(){
if(seconds == 0){
timer.cancel();
trigger.addMouseListener(mL);
return;
}
seconds--;
msg.setText("Attempting to add listener in : "+seconds);
}
};
timer.scheduleAtFixedRate(task, 1000, 1000);
}
}
Okay, this example sets up two state variables, one to determine if the mouse has entered or exited the button and one which determines if the timer has completed or not.
If these two conditions are true, then the border is set.
This means that the border of the react button WON'T be changed if the mouse is NOT over the trigger button when the timer runs out, but if the user moves back into the button, it will be changed. It will also be changed in the mouse is over the trigger button AND the timer runs out
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
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 static class TestPane extends JPanel {
public static final Border PANEL_BORDER = new LineBorder(Color.red, 12);
private boolean mouseInTheHouse = false;
private boolean timedOut = false;
private JButton react;
private JButton trigger;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.ipadx = 200;
gbc.ipady = 60;
gbc.gridwidth = GridBagConstraints.REMAINDER;
react = new JButton("React");
trigger = new JButton("Trigger");
add(react, gbc);
add(trigger, gbc);
trigger.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
mouseInTheHouse = true;
stateChanged();
}
#Override
public void mouseExited(MouseEvent e) {
mouseInTheHouse = false;
}
});
Timer timer = new Timer(4000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timedOut = true;
System.out.println("!!");
stateChanged();
}
});
timer.start();
}
protected void stateChanged() {
if (mouseInTheHouse && timedOut) {
react.setBorder(PANEL_BORDER);
}
}
}
}
Note, that I've not setup a condition for what should happen when the mouse leaves the trigger button, but I assume you'd reset the border.
I see. I have an additional question. What if I had 10 trigger buttons (top of the panel) and 10 react button (bottom of the panel)? The condition is: If I have my mouse over one of the trigger button, then the corresponding react button of the same position plus the react button to the right side of that react button will have borders. How do I detect that without looping through my button List and detecting mouseInHouse?
Basically, distill the idea down to it's most common level. You have two buttons, a Timer, MouseListener and two state variables. Wrap these up into a common class which you can then reuse.
public class ButtonStateManager {
private boolean mouseInTheHouse = false;
private boolean timedOut = false;
private JButton trigger;
private JButton react;
private Timer timer;
public ButtonStateManager(JButton trigger, JButton react, int timeOut) {
this.trigger = trigger;
this.react = react;
trigger.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
mouseInTheHouse = true;
stateChanged();
}
#Override
public void mouseExited(MouseEvent e) {
mouseInTheHouse = false;
}
});
Timer timer = new Timer(timeOut, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timedOut = true;
stateChanged();
}
});
}
protected void stateChanged() {
if (mouseInTheHouse && timedOut) {
react.setBorder(TestPane.PANEL_BORDER);
}
}
}
Now, this assumes there's a relationship between the two buttons.
If your mouse is on the trigger button, and then MouseListener is added to the button, it cannot capture the previously happened event of entering the trigger button's area.
If you insist on showing the border when your mouse is on the trigger button without getting off and on it again, you should call the mouseEnter method manually after you add the mouseListener to it:
(before that you should pass the final JFrame frame to your countDown method)
if(seconds == 0){
timer.cancel();
trigger.addMouseListener(mL);
Point mousePosition = MouseInfo.getPointerInfo().getLocation();
Rectangle triggerRect = trigger.getBounds();
Rectangle frameRect = frame.getBounds();
Rectangle newRect = new Rectangle(triggerRect.x + frameRect.x, triggerRect.y + frameRect.y, triggerRect.width, triggerRect.height);
if(newRect.contains(mousePosition)) {
mL.mouseEntered(new MouseEvent(trigger, 0, System.currentTimeMillis(), 1, 0, 0, 0, false));
}
return;
}
But as MadProgrammer mentioned your question is not clear by saying "I'm trying to have the react button appear with a border after the timer has ended".
Hope this helps!
I have switched my Layout to a AbsoluteLayout and everything is in place where it needs to be, but when I run my program, my JButtons are invisible until I mouse over them. What should I change so they are always visible, mouse entered or not?
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.Cursor;
public class Library extends JFrame implements ActionListener, MouseListener {
private JFrame jf1;
private JPanel jp1;
private JTextField jtf1;
private JTextField jtf2;
private JTextField jtf3;
private JButton jb1;
private JButton jb2;
private JButton jb3;
public Library() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(Exception ee) {
ee.printStackTrace();
}
JFrame.setDefaultLookAndFeelDecorated(false);
jf1 = new JFrame("Library");
jf1.setVisible(true);
jf1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf1.setSize(1080, 900);
jf1.setResizable(true);
jf1.getContentPane().setLayout(null);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
jf1.setLocation(dim.width/2-jf1.getSize().width/2, dim.height/2-jf1.getSize().height/2);
jp1 = (JPanel) jf1.getContentPane();
jb1 = new JButton("Genre");
jb1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
jb1.setBounds(345, 11, 150, 60);
jb1.addActionListener(this);
jb2 = new JButton("Author");
jb2.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
jb2.setBounds(494, 11, 150, 60);
jb2.addActionListener(this);
jb3 = new JButton("Title");
jb3.setDefaultCapable(false);
jb3.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
jb3.setBounds(643, 11, 150, 60);
jb3.addActionListener(this);
jtf2 = new JTextField("Enter Text");
jtf2.setBounds(445, 292, 200, 20);
jtf2.addMouseListener(this);
jtf2.setVisible(false);
jtf3 = new JTextField("Enter Text");
jtf3.setBounds(671, 351, 200, 20);
jtf3.addMouseListener(this);
jtf3.setVisible(false);
jp1.add(jtf2);
jtf1 = new JTextField("Enter Text");
jtf1.setBounds(236, 230, 200, 20);
jtf1.addMouseListener(this);
jtf1.setVisible(false);
jp1.add(jtf1);
jp1.add(jtf3);
jp1.add(jb1);
jp1.add(jb2);
jp1.add(jb3);
jf1.validate();
}
#Override
public void actionPerformed(ActionEvent e) {
Object code = e.getSource();
if (code == jb1) {
jtf1.setVisible(true);
jp1.validate();
}
else if (code == jb2) {
jtf2.setVisible(true);
jp1.validate();
}
else if (code == jb3) {
jtf3.setVisible(true);
jp1.validate();
}
}
public static void main(String[] args) {
Library shoe = new Library();
}
#Override
public void mouseClicked(MouseEvent eee) {
Object mouseCode = eee.getSource();
if(mouseCode == jtf1) {
jtf1.selectAll();
}
if(mouseCode == jtf2) {
jtf2.selectAll();
}
if(mouseCode == jtf3) {
jtf3.selectAll();
}
}
#Override
public void mouseEntered(MouseEvent eee) {}
#Override
public void mouseExited(MouseEvent eee) {}
#Override
public void mousePressed(MouseEvent eee) {}
#Override
public void mouseReleased(MouseEvent eee) {}
}
There are multiple errors in your program:
You're using AbsoluteLayout which in the end it's still a null layout, see Null layout is evil and Why is it frowned upon to use a null layout in Swing?. While absolute positioning might seem like the fastest and easiest way to make complex GUI's for Swing beginners, the more you advance in your program the more errors you'll get due to this. Instead use a Layout Manager or combinations of them along with Empty borders for extra spacing if needed.
You're creating a JFrame object and extending JFrame that, in other words, makes your class a JFrame! There's no need to extend JFrame if you really need to extend something extend a JPanel which can be added later into other components while JFrame can't.
You're making your JFrame visible before you have added all your components to it, that's the reason for your error, and probably the 1st one too. You should make it visible only in the end, after you have added all your components to it.
Set the JFrame visible (jf1.setVisible(true);) after you add all components. (End of your constructor)
I am using WindowBuilder to create a GUI.
I'm kinda new to JFrame and I have a problem: I added a JSpinner and I want to save the number that I put in my spinner to an int so I can use it later on. Can someone please help me? Thanks.
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import javax.swing.SwingConstants;
import java.awt.Font;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import java.awt.Color;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class frame1 {
private JFrame frame;
private JTextField txtHoeveelEuroWil;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame1 window = new frame1();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public frame1() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JSpinner spinner = new JSpinner();
spinner.setModel(new SpinnerNumberModel(20, 20, 500, 20));
spinner.setBounds(116, 100, 200, 50);
frame.getContentPane().add(spinner);
int value;
JButton btnNewButton = new JButton("OK");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//value=Integer.parseint ???
//what should I type here to save the number that I entered
//in the spinner?
}
});
btnNewButton.setBounds(172, 177, 89, 32);
frame.getContentPane().add(btnNewButton);
}
}
Try this
try {
spinner.commitEdit();
}
catch (ParseException pe) {{
// Edited value is invalid, spinner.getValue() will return
// the last valid value, you could revert the spinner to show that:
JComponent editor = spinner.getEditor()
if (editor instanceof DefaultEditor) {
((DefaultEditor)editor).getTextField().setValue(spinner.getValue());
}
// reset the value to some known value:
spinner.setValue(fallbackValue);
// or treat the last valid value as the current, in which
// case you don't need to do anything.
}
int value = (Integer)spinner.getValue();
To save the value and use it, you can set a field variable to hold it. So in your fram1 class, add a getter and setter for the variable. Then set the variable on button click.
public class frame1 {
//default to -1
private int spinnerValue = -1;
private void setSpinnerValue(aValue) {
spinnerValue = aValue;
}
public int getSpinnerValue() {
return spinnerValue;
}
private void initialize() {
// blah blah
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// here set a value
setSpinnerValue((Integer) spinner.getValue());
}
});
}
}
then when you need the value, you can use the instance of frame1 and call this method
frame1.getSpinnerValue();
So if a user do not press any button,the action listener is not triggered and i end up with an exception. So i thought to put a default String in my FrameClass and change that String whenever a button is clicked,than in my main class i do a loop that keeps on looping until the default String is changed,so i think it is an infinite loop. Is it okay to do that ?
package gui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRootPane;
/**
*
* #author E-TECH
*/
public class ButtonsFrame extends JFrame {
private JButton ScPerF, weekSc, both,cancel;
private SchedulePerWeek week;
private CoursesPerWeek course;
private JPanel panel;
private String choice;
private File file;
public ButtonsFrame() {
ScPerF = new JButton("Generate schedule/faculty");
weekSc = new JButton("Generate weekly class schedule");
both = new JButton("Generate Both");
cancel = new JButton("Cancel");
choice="nothing";
ScPerF.addActionListener(new ButtonListener());
weekSc.addActionListener(new ButtonListener());
both.addActionListener(new ButtonListener());
cancel.addActionListener(new ButtonListener());
setResizable(false);
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.NONE);
panel = new JPanel();
panel.add(ScPerF);
panel.add(weekSc);
panel.add(both);
panel.add(cancel);
getContentPane().add(panel);
setVisible(true);
pack();
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == ScPerF) {
dispose();
choice = "faculty";
}
if (event.getSource() == weekSc) {
dispose();
choice = "course";
}
if (event.getSource() == both) {
dispose();
choice = "both";
}
if (event.getSource()==cancel){
dispose();
choice="cancel";
}
}
}
public boolean Activated() {
return ScPerF.isSelected() || weekSc.isSelected();
}
public String getChoice() {
return choice;
}
public File getFile() {
return file;
}
}
public class SchedulePerWeek {
HSSFSheet weekSh,courseSh;
int instructor_count;
HSSFWorkbook wb;
public SchedulePerWeek() {
ExcelReader reader = new ExcelReader();
HSSFSheet sh = reader.getSortedSheet();
String choice=reader.getChoice();
if(choice.equals("cancel")||choice.equals("nothing")){///i fixed the exception with this condition by closing the program instead of continuing,but i want to wait for the user instead of just exiting the program
System.exit(1);
}
wb = new HSSFWorkbook();
/////
///more code
I ran your code from a couple of edits ago, and it works fine on my Windows 8 workstation, Java 7.
Before you go much further in your GUI design, read this answer to The Use of Multiple JFrames, Good/Bad Practice?
I modified your code to use a JFrame, rather than extend one. You should only extend a Swing component when you override one of the component methods.
You only need to define your Button listener once. You set the listener on your buttons.
I changed the JFrame default close operation to exit on close.
I added a main method so I could run your code.
Here's the code with the changes.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
/**
*
* #author E-TECH
*/
public class ButtonsFrame{
private JButton scPerf, weekSc, both, cancel;
// private SchedulePerWeek week;
// private CoursesPerWeek course;
private JFrame frame;
private JPanel panel;
private String choice;
private File file;
public ButtonsFrame() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
scPerf = new JButton("Generate schedule/faculty");
weekSc = new JButton("Generate weekly class schedule");
both = new JButton("Generate Both");
cancel = new JButton("Cancel");
choice = "nothing";
ButtonListener listener = new ButtonListener();
scPerf.addActionListener(listener);
weekSc.addActionListener(listener);
both.addActionListener(listener);
cancel.addActionListener(listener);
frame.setResizable(false);
frame.setUndecorated(true);
frame.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
panel = new JPanel();
panel.add(scPerf);
panel.add(weekSc);
panel.add(both);
panel.add(cancel);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == scPerf) {
frame.dispose();
choice = "faculty";
}
if (event.getSource() == weekSc) {
frame.dispose();
choice = "course";
}
if (event.getSource() == both) {
frame.dispose();
choice = "both";
}
if (event.getSource() == cancel) {
frame.dispose();
choice = "cancel";
}
}
}
public boolean Activated() {
return scPerf.isSelected() || weekSc.isSelected();
}
public String getChoice() {
return choice;
}
public File getFile() {
return file;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ButtonsFrame();
}
});
}
}