Working in Java: I have a JFrame class, and separate classes for my two JPanels that are added to the JFrame. One of the JPanel classes has some buttons in it, which can interact with each other(when I click on one button, it can disable another button). However, I can't figure out how to get the button to call a method in the other JPanel (written in a separate class).
So, my program look like this:
JFrame
Jpanel1
Jpanel2 - This class has my buttons in it, I'm trying to get them to interact with the JPanel1 object.
Any tips appreciated, thanks!
One way to do this is to pass an instance of (to use your terminology) Jpanel1 into Jpanel2. This doesn't have to be done in the constructor, you can have a setConnectedPanel(JPanel) method, for example.
Here's some code that demonstrates what you want to do:
MyFrame.java
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class MyFrame extends JFrame {
public MyFrame() {
ReactionPanel rp = new ReactionPanel();
ActionPanel ap = new ActionPanel(rp);
setLayout(new GridLayout(2, 1));
add(ap);
add(rp);
pack();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MyFrame();
}
});
}
}
ActionPanel.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class ActionPanel extends JPanel implements ActionListener {
private ReactionPanel rp;
private JButton button;
public ActionPanel(ReactionPanel rp) {
this.rp = rp;
button = new JButton("Click");
button.addActionListener(this);
this.add(button);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(button)) {
rp.react();
}
}
}
ReactionPanel.java
import javax.swing.JLabel;
import javax.swing.JPanel;
public class ReactionPanel extends JPanel {
private JLabel label;
public ReactionPanel() {
label = new JLabel("PING");
this.add(label);
}
public void react() {
if(label.getText().equals("PING")) {
label.setText("PONG");
} else {
label.setText("PING");
}
}
}
As you can see, I tend to override all of my JFrames/JPanels when I write Swing GUIs as I find it easier and more flexible but YMMV.
Related
I'm having a problem with JButton. I need to change the text on the goPauseButton when it has been clicked, but I get this error: goPauseButton cannot be resolved. I'm quite new to Java, so I started trying to solve the issue using techniques from other languages such as Free Pascal. There you need to refer to the class where the button is in, and then the button. In my code it would look like this:
PrisonersDilemma.goPauseButton.setText("Pause");
But then I get this error: Cannot make a static reference to the non-static field PrisonersDilemma.goPauseButton
This is my code (so far), I've erased unimportant things:
Main class
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.util.Hashtable;
//...
public class PrisonersDilemma /* possible extends... */ {
// declaring
JFrame frame;
PlayingField field;
JPanel componentPanel;
public JButton goPauseButton;
public JPanel createComponentPanel() {
componentPanel = new JPanel();
componentPanel.setLayout(new GridLayout(2,6));
// set goPauseButton
goPauseButton = new JButton("GO!");
goPauseButton.addActionListener(field);
goPauseButton.setBounds(110,350, 80,20); // first coordinates, then size
frame.add(goPauseButton);
return componentPanel;
}
void buildGUI() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
field = new PlayingField();
// set frame
frame = new JFrame("Prisoners Dilemma");
frame.add(field);
createComponentPanel();
frame.add(field, BorderLayout.CENTER);
frame.setLocation(200, 200);
frame.pack();
frame.setVisible(true);
frame.setSize(400, 450);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
} );
}
Class with ActionEventHandler
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.JButton;
public class PlayingField extends JPanel
implements ActionListener,
ChangeListener {
private boolean started;
#Override
public void actionPerformed(ActionEvent e) {
// TODO
if ("GO!".equals(e.getActionCommand())){
System.out.println("GO!");
started = true;
goPauseButton.setText("Pause"); // here is the error
} else if ("Pause".equals(e.getActionCommand())){
System.out.println("Pause");
started = false;
} else if ("Reset".equals(e.getActionCommand())){
System.out.println("Reset");
}
}
}
I think you need to change the way you're approaching the problem. The PlayingField has no responsibility for modifying the state of the goPauseButton in PrisonersDilemma. Instead, PrisonersDilemma should update the goPauseButton and call an appropriate method of PlayingField
For example...
goPauseButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
goPauseButton.setText("Pause");
field.start();
}
});
And...
public class PlayingField extends JPanel {
public void start() {
System.out.println("GO!");
started = true;
}
public void pause() {
started = false;
System.out.println("Pause");
}
public void reset() {
System.out.println("Reset");
}
}
I am programming a multiplication app for very large integers, I need to update every sigle step of the multiplication in a Swing component ( I created a JPane extended class with a JTextArea in it, then add it to the JFrame inside a ScrollPane). The issue is that this Swing component only updates once the multiplication algorithm is done. I tried using a Thread that would call repaint method of the Pane every 10 ms, but it did not work. The next is a sample of the problem.
This is the main Frame class:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Frame extends JFrame implements ActionListener{
private Console console;
private JButton calculate;
private Calculator calculator;
public Frame(){
console=new Console();
calculate=new JButton("Calculate");
calculate.addActionListener(this);
calculate.setActionCommand("");
calculator=new Calculator(this);
this.setLayout(new BorderLayout());
this.add(console,BorderLayout.CENTER);
this.add(calculate, BorderLayout.NORTH);
this.setTitle("Frame");
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(new Dimension(500,500));
this.setLocationRelativeTo(null);
}
public void writeOnConsole(String txt){
console.write(txt);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand().equals("")){
console.clear();
calculator.calculate();
}
}
public static void main(String[] args) {
new Frame();
}
}
This is the Console Class
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.TitledBorder;
public class Console extends JPanel{
private JTextArea area;
public Console(){
this.setBorder(new TitledBorder("Console:"));
area=new JTextArea();
this.setLayout(new BorderLayout());
JScrollPane scroll=new JScrollPane(area);
this.add(scroll,BorderLayout.CENTER);
}
public void clear(){
area.setText("");
}
public void write(String txt){
area.append(txt+"\n");
}
}
Finally, this is the Calculator class (the one responsible for calling the writing)
public class Calculator {
private Frame parent;
public Calculator(Frame f){
parent=f;
}
public void calculate(){
for (int i = 0; i <= 1000000; i++) {
parent.writeOnConsole("Iteration "+i);
}
}
}
Note that if you run the program, the GUI will freeze until the Calculator class is done with the loop.
if you have a layout like a BorderLayout and you want to update it inside the JFrame do as bellow
JFrame frame = new JFrame();
BorderLayout layout = new BorderLayout();
layout.layoutContainer(frame.getContentPane());// use the frame as the border layout container
else you can use JFrame pack() method. The pack method packs the components within the window based on the component’s preferred sizes. it's not for updating but it updates the JFrame which is kind of a trick
JFrame frame = new JFrame();
//change the components dynamically
frame.pack();
or use Container methdod validate(). Validating a container means laying out its subcomponents. Layout-related changes, such as setting the bounds of a component, or adding a component to the container.
JFrame frame = new JFrame();
Container container = frame.getContentPane();
container.validate();
or if you want to update an specific component use
Component component = new JPanel();
component.repaint();
If this component is a lightweight component, repaint() method causes a call to this component's paint method as soon as possible .
or if you want for example numerous changes happen one by one dynamically then you could use the code below which is completely different from the things i said above. for that you could use platform.runlater() inside another thread which deals with everything that is about to change in realtime
new Thread(new Runnable()
{
#Override
public void run()
{
Platform.runLater(new Runnable()//use platform.runlater if you are using javafx
{
#Override
public void run()
{
try
{Thread.sleep(50);}catch(Exception e){}//use it in for loop where changes happen
//do some realtime change of components
}
});
}).start();
your Console class would be
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.TitledBorder;
public class Console extends JPanel{
private JTextArea area;
public Console(){
this.setBorder(new TitledBorder("Console:"));
area=new JTextArea();
this.setLayout(new BorderLayout());
JScrollPane scroll=new JScrollPane(area);
this.add(scroll,BorderLayout.CENTER);
}
public void clear(){
area.setText("");
}
public void write(String txt){
area.append(txt+" "+"\n");
}
}
and the Calculator class is
public class Calculator {
private Frame parent;
public Calculator(Frame f){
parent=f;
}
public void calculate(){
new Thread(new Runnable() {
#Override
public void run()
{
for (int i = 0; i <= 100; i++) {
try
{
Thread.sleep(50);
}
catch(Exception e)
{
e.printStackTrace();
}
parent.writeOnConsole("Iteration "+i);
}
}
}).start();
}
}
as you can see i used another thread to do the changes
try the update method to call paint method for maintain every change
I have two classes mainpanel.java and subpanel.java. The subpanel.class contains a checkbox and some labels. I want to change the setSelected() and setText() of these components when i click some buttons in the mainpanel.java .
I have created a method in subpanel.java which i call from mainpanel.java and pass the boolean values.
public void schedulerchange(boolean check){
System.out.println("checked"+check);
scheduleenabler.setEnabled(check);
scheduleenabler.setSelected(check);
scheduleinfo.setText("Scheduler in On");
//subpanel21.updateUI();
}
When i call this function from mainpanel.java the function is called but the values don't change unless i make jcheckbox and jlabel static. But from what i learned we should not use static components unless very necessary.
Is there some other way to change the components?
If I have understood your question then I think you want to write a separate ActionListener class and perform action there which will enable or disable the JCheckBox in the UI-class. The below code shows that. Pass your checkbox reference to that PerformAction class and make it enabled or disabled by clicking on the button.
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MainClass {
MainClass() {
JFrame jfrm = new JFrame("JTable Demo");
jfrm.setLayout(new FlowLayout());
jfrm.setSize(460, 180);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JCheckBox check = null;
// Get the Panel from the subclass;
JPanel panel = new CheckBox().getCheckBoxPanel();
// From the compoenents present in the panel get the CheckBox compoenent.
for(int i = 0; i < panel.getComponentCount(); i++) {
if(panel.getComponent(i) instanceof JCheckBox) {
check = (JCheckBox) panel.getComponent(i);
}
}
JButton button = new JButton("Click");
// Pass the CheckBox Compoenent to the ActionListener.
button.addActionListener(new PerformAction(check));
jfrm.add(button);
jfrm.add(panel);
jfrm.setVisible(true);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MainClass();
}
});
}
}
class PerformAction implements ActionListener {
JCheckBox check = null;
public PerformAction(JCheckBox checkBox) {
check = checkBox;
}
#Override
public void actionPerformed(ActionEvent e) {
boolean checkStatus = check.isSelected();
if(checkStatus == true) {
check.setEnabled(false);
check.setSelected(false);
} else {
check.setEnabled(true);
check.setSelected(true);
}
}
}
class CheckBox {
public JPanel getCheckBoxPanel() {
JPanel checkPanel = new JPanel();
JCheckBox check = new JCheckBox();
checkPanel.add(new JLabel("CheckBox"));
checkPanel.add(check);
return checkPanel;
}
}
This is not an appropriate use of updateUI(), which "Resets the UI property to a value from the current look and feel." Using revalidate(), as suggested in a comment, would be helpful only if components are added to, or removed from, the enclosing Container. Instead, invoke repaint() directly on the sub-panel instance. For greater flexibility, use the observer pettern suggested here.
Addendum: This example use Action to encapsulate the button's behavior. Because the checkbox's selected state is a bound property, the component is repainted automatically, but you can invoke repaint() explicitly if needed.
Addendum: Update to pass a reference as a parameter.
Addendum: In this variation, the parameter is a reference to the exported Action.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** #see https://stackoverflow.com/a/14412516/230513 */
public class Example {
private void display() {
JFrame f = new JFrame("Example");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridLayout(0, 1));
JPanel panel = new JPanel();
final JCheckBox check = new JCheckBox("Check");
Action checkAction = new AbstractAction("Update") {
#Override
public void actionPerformed(ActionEvent e) {
check.setSelected(!check.isSelected());
}
};
panel.add(check);
f.add(panel);
f.add(new SubPanel(checkAction));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class SubPanel extends JPanel {
public SubPanel(final Action action) {
this.add(new JButton(action));
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Example().display();
}
});
}
}
I am very new to Java AWT. My question header must seem ridiculous to you, sorry about that. In my application I have three buttons which display different threads when clicked on. Now I want to add maybe a button or checkboxes or choicelist, etc when clicked on a particular button. For eg, if I click on yes button, it should display a choice list, something like that. How do I achieve something like that? Here is my code so far:
import java.awt.Button;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class AppWindow extends Frame implements ActionListener{
String keymsg = "Test message";
String mousemsg = "Nothing";
int mouseX=30, mouseY=30;
String msg;
public AppWindow(){
//addKeyListener(new MyKeyAdapter(this));
//addMouseListener(new MyMouseAdapter(this));
addWindowListener(new MyWindowAdapter());
}
public void paint(Graphics g){
g.drawString(msg, 150, 100);
}
//Here the window is created:
public static void main(String args[]){
AppWindow appwin = new AppWindow();
appwin.setSize(new Dimension(300,200));
appwin.setTitle("My first AWT Application");
appwin.setLayout(new FlowLayout(FlowLayout.LEFT));
appwin.setVisible(true);
Button yes,no,maybe;
yes = new Button("yes");
no = new Button("no");
maybe = new Button("maybe");
appwin.add(yes);
appwin.add(no);
appwin.add(maybe);
yes.addActionListener(appwin);
no.addActionListener(appwin);
maybe.addActionListener(appwin);
}
#Override
public void actionPerformed(ActionEvent ae) {
// TODO Auto-generated method stub
String str = ae.getActionCommand();
if(str.equals("yes")){
msg = "You pressed Yes";
}
if(str.equals("no")){
msg = "You pressed No";
}
if(str.equals("maybe")){
msg = "You pressed Maybe";
}
repaint();
}
}
class MyWindowAdapter extends WindowAdapter {
public void windowClosing(WindowEvent we){
System.exit(0);
}
}
Points describing what you should be doing :
As already mentioned by others, better to use Swing over AWT, since Swing is more advanced.
As much as possible, always try to Paint on top of a JPanel or a
JComponent, instead of Painting right on top of your JFrame, by
overriding the paintComponent(Graphics g) method of the said
JComponent/JPanel
Never call setVisible(true) on the JFrame until and unless it's
size has been established. So in general terms, this has to be the
last call, once you are done adding components to the JFrame and
the size of the JFrame has been realized by the LayoutManager.
Inside your actionPerformed(...), instead of writing all if
statement blocks, you should adhere to the if-else if statement
blocks. The benefit of this, over the former is that, at any given
time, only one event will be fired, hence once the said condition is
satisfied, you don't want your code to keep checking other
conditions, which in general is really not a good programming
practice, IMHO.
MOST IMPORTANT THING : Never make calls like pack()/setVisible(...) from within the main method, such calls belong
to the Event Dispatch Thread, and must be done on the same. Please
read Concurrency in Swing for more detail.
Have a look at the example program, for better understanding.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ComponentExample
{
private CustomPanel drawingBoard;
private JPanel contentPane;
private JButton yesButton;
private JButton noButton;
private JButton maybeButton;
private JComboBox cbox;
private ActionListener buttonAction = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
JButton button = (JButton) ae.getSource();
if (cbox.isShowing())
contentPane.remove(cbox);
if (button == yesButton)
{
drawingBoard.setText("You Pressed YES.");
contentPane.add(cbox, BorderLayout.PAGE_END);
}
else if (button == noButton)
drawingBoard.setText("You Pressed NO.");
else if (button == maybeButton)
drawingBoard.setText("You Pressed MAYBE.");
/*
* revalidate()/repaint() is needed
* when the JComponent is added or
* removed from the already
* visible Container.
*/
contentPane.revalidate();
contentPane.repaint();
}
};
public ComponentExample()
{
cbox = new JComboBox(
new String[]{"I GOT IT"
, "I STILL HAD DOUBT"});
}
private void displayGUI()
{
JFrame frame = new JFrame("Component Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setOpaque(true);
contentPane.setBackground(Color.DARK_GRAY);
contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(5, 5));
JPanel buttonPanel = new JPanel();
buttonPanel.setOpaque(true);
buttonPanel.setBackground(Color.WHITE);
yesButton = new JButton("YES");
yesButton.addActionListener(buttonAction);
noButton = new JButton("NO");
noButton.addActionListener(buttonAction);
maybeButton = new JButton("MAY BE");
maybeButton.addActionListener(buttonAction);
buttonPanel.add(yesButton);
buttonPanel.add(noButton);
buttonPanel.add(maybeButton);
contentPane.add(buttonPanel, BorderLayout.PAGE_START);
drawingBoard = new CustomPanel();
contentPane.add(drawingBoard, BorderLayout.CENTER);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ComponentExample().displayGUI();
}
});
}
}
class CustomPanel extends JPanel
{
private String msg;
public CustomPanel()
{
msg = "";
setOpaque(true);
setBackground(Color.WHITE);
}
public void setText(String msg)
{
this.msg = msg;
repaint();
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(300, 300));
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawString(msg, getWidth() / 3, getHeight() / 3);
}
}
I don't know if I have understood the question well but... couldn't you create those elements and call their setVisible(boolean) methods to make them not visible at first, and them make them visible when user pushes buttons?
I'm new to java coming from C# so I'm not familiar with java best practices.
I have a main class that opens a JFrame to get several input strings from a user. When the user clicks submit the GUI should close and the main class continue processing using the input.
This is the main class:
public class Main {
FInput fInput;
public void main(String[] args) {
if(args.length==0)
{
fInput = new FInput();
fInput.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fInput.pack();
fInput.setVisible(true);
}
else
startProcess(args);
}
public void startProcess(String[] args) {
// Do stuff
}
The main class will use this frame to get input from the user:
public class FInput extends JFrame{
private JTextField txtSourceDirectory;
private JTextField txtTargetDirectory;
private JTextField txtDefectNumber;
private JTextField txtSliceTokens;
private JButton btnStart;
public FInput() {
// Initialize text fields and button
JButton.addActionListener(something);
}
}
In all the examples I could find, the listener would be a FMain itself. However in this case I want Main to listen and use the input in method startProcess.
Would having Main implement ActionListener, and passing it to FMain constructor is the way to go?
Yes, that is the right idea. You must do two things in order to be able to do that, though:
Put this at the beginning of the FInput class:
Main m = new Main(this);
Then, put these lines somewhere in the Main class...
FInput gui;
public Main(FInput in) { gui = in; }
Now you can refer to any component in the FInput class from the Main class by doing something like this.
gui.someComponent ...
To set up listeners just write someComponent.addItemListener(m); or something of the sort.
Hope this helps!
#Yoav In response to your latest comment...
You don't have to separate the listening class from the GUI class; you can combine the two into one class...
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JFrame implements ActionListener {
private JTextField txtSourceDirectory;
private JTextField txtTargetDirectory;
private JTextField txtDefectNumber;
private JTextField txtSliceTokens;
private JButton btnStart;
public Main() {
txtSourceDirectory = new JTextField(40); //change this to the amount of characters you need
txtTargetDirectory = new JTextField(40);
txtDefectNumber = new JTextField(40);
txtSliceTokens = new JTextField(40);
btnStart = new JButton("Start");
add(txtSourceDirectory);
add(txtTargetDirectory);
add(txtDefectNumber);
add(txtSliceTokens);
add(btnStart);
btnStart.addActionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent event) {
//do stuff
}
static void startProcess(String[] ARGS) {
//do stuff
}
public static void main(String[] args) {
if (args.length == 0) {
Main frame = new Main();
} else {
startProcess(args);
}
}
}
Also consider using JOptionPane, shown here, in your Main class. You can customize the appearance, including button text, as shown in How to Make Dialogs.
First main method in java always must be public static void. Below is example how this can be done.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* Main class is frame but also implements ActionListener interface.
*/
public class Main extends JFrame implements ActionListener {
private JButton btnStart;
private static Main frame;
public Main() {
JPanel panel = new JPanel();
btnStart = new JButton("Press me");
// Add action listener. Listener could be any class that implements
// ActionListener
btnStart.addActionListener(this);
// This means add button btnStart to panel
panel.add(btnStart);
// This means add panel to frame
this.add(panel);
}
// main method in java always must be public, static and void. You forgot to
// put static.
public static void main(String[] args) {
if (args.length == 0) {
frame = new Main();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
} else
frame.startProcess(args);
}
public void startProcess(String[] args) {
// TODO
}
#Override
public void actionPerformed(ActionEvent arg0) {
// Here you put your code that is executed every time you press button.
// For example you just want to show message.
JOptionPane.showMessageDialog(this, "You pressed Button.");
}
}
But it is much better to have special class. For example:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class ButtonListener implements ActionListener {
JFrame parent;
public ButtonListener(JFrame parent) {
this.parent = parent;
}
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(parent, "You pressed Button");
}
}
And in the main class you just add action listener to button:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* Main class is frame but also implements ActionListener interface.
*/
public class Main extends JFrame {
private JButton btnStart;
private static Main frame;
public Main() {
JPanel panel = new JPanel();
btnStart = new JButton("Press me");
ButtonListener listener = new ButtonListener(this);
// Add action listener. Listener could be any class that implements
// ActionListener
btnStart.addActionListener(listener);
// This means add button btnStart to panel
panel.add(btnStart);
// This means add panel to frame
this.add(panel);
}
// main method in java always must be public, static and void. You forgot to
// put static.
public static void main(String[] args) {
if (args.length == 0) {
frame = new Main();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
} else
frame.startProcess(args);
}
public void startProcess(String[] args) {
// TODO
}
}