Java thread is repeating the swing form - java

I am using java threads to manage multiple (3) programs concurrently.
1 is for Java swing form(draws UI for input), 1 is for setting an icon at systemtray (launchs immediate after taking input from UI), and 1 is for Processing inputs and reflect it to the SystemTray icon (in form of a popup message to that Tray Icon).
Earlier, I tried without separate Threads but the problem I was facing is "if the execution control once goes forward (from UI to next Process) where some repetitive task are performed using thread.sleep() method (that holds the control actually for entire time).Hence the earlier forms(UI) remains unresponsive (we cant even close the form that time).
So, I thought to implement separate threads for each of three. But as soon as I try to launch The Form (UI), it goes repetitive in infinite loop actually.
Here, is the code:
public class ImprovedImplementation {
public static void main(String[] args) {
System.out.println("Main thread is started...");
new LauncherUI();
}
}
class LauncherUI implements Runnable {
private JFrame mainFrame;
private JLabel headerLabel;
private JLabel statusLabel;
private JPanel controlPanel;
String textFieldValue = null;
Thread launcher ;
LauncherUI()
{
prepareGUI();
launcher = new Thread(this, "Launcher Thread");
System.out.println("launcher thread created" + launcher);
launcher.start();
}
public void run()
{
try
{
LauncherUI swingControlDemo = new LauncherUI();
swingControlDemo.showEventDemo();
}
catch(Exception e)
{
System.out.println("launcher thread interrupted");
}
System.out.println("launcher run is over" );
}
private void prepareGUI() {
mainFrame.setSize(450, 400);
mainFrame.setLayout(new GridLayout(3, 1));
mainFrame.setLocationRelativeTo(null);
headerLabel = new JLabel("", JLabel.CENTER);
statusLabel = new JLabel("", JLabel.CENTER);
statusLabel.setSize(350, 100);
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.exit(0);
}
});
controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
mainFrame.add(headerLabel);
mainFrame.add(controlPanel);
mainFrame.add(statusLabel);
mainFrame.setVisible(true);
mainFrame.setResizable(false);
}
private void showEventDemo() {
headerLabel.setText("Welcome to the Web Server Tracking System !!");
headerLabel.setFont(new Font("serif", Font.BOLD, 20));
JLabel l = new JLabel();
l.setText("Enter All (Servers) URLs separated by a comma ( , ) :");
l.setFont(new Font("Serif", Font.BOLD, 16));
JLabel l2 = new JLabel();
l2.setText("[for example: google.com,wikipedia.org,sjsu.edu]");
l2.setFont(new Font("Serif", Font.BOLD, 15));
JTextField txt = new JTextField(30);
JButton submitButton = new JButton("Start Tracking");
JButton cancelButton = new JButton("Close");
submitButton.setActionCommand("Start");
cancelButton.setActionCommand("Cancel");
submitButton.addActionListener(new ButtonClickListener());
submitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
textFieldValue = txt.getText();
// textFieldValue="Hello";
// .... do some operation on value ...
}
});
cancelButton.addActionListener(new ButtonClickListener());
controlPanel.add(l);
controlPanel.add(l2);
controlPanel.add(txt);
controlPanel.add(submitButton);
controlPanel.add(cancelButton);
mainFrame.setVisible(true);
}
private class ButtonClickListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("Start")) {
if (textFieldValue.equals("") || textFieldValue.indexOf(".") == -1) {
statusLabel.setText("Please Enter Some Server Urls, Before Start Tracking.");
if (textFieldValue.indexOf(".") == -1 && !textFieldValue.equals("")) {
statusLabel.setText("Please Enter Valid Urls.");
}
statusLabel.setForeground(Color.RED);
} else {
StringTokenizer urlValues = new StringTokenizer(textFieldValue, ",");
Vector v = new Vector();
while (urlValues.hasMoreTokens()) {
String token = urlValues.nextToken();
v.add(token);
}
String[] urlStrArray = (String[]) v.toArray(new String[v.size()]);
System.out.println("Took following URLS from the User:");
for(int m=0; m < urlStrArray.length;m++){
System.out.println(urlStrArray[m]);
}
statusLabel.setText("Tracking is started . . . it's pinned in your System Tray ( Task bar ).");
statusLabel.setForeground(Color.BLACK);
}
} else {
System.exit(0);
}
}
}
}
Can anyone Help me out.
It would be highly appreciated.

Your main() does a new LauncherUI().
Your LauncherUI constructor calls start() on a Runnable; the run() method calls new LauncherUI(). That constructor calls start(), repeating the process; classic endless loop.

Related

Java AWT/Swing Updating JPanel Continously Not Working

I am trying to make a program that populates a JPanel with GridLayout with the contents of a HashMap that contains String keys to JButton values. Because the size of the HashMap may change, I can't just use setText() for each button. So far I've called .removeAll() to remove the JPanel of all buttons, then I loop through the HashMap to repopulate the JPanel. I then call revalidate() on the JPanel and repaint() on the JFrame.
Current Code:
public class GUI implements Runnable, ActionListener
{
private ToDo td;
JFrame frame;
Thread t=null;
int fontsize = 18;
private Container contentPane;
private JPanel topPane;
private JButton main;
private JButton add;
private JButton settings;
private JPanel centerPane;
private JScrollPane centerScroll;
private JPanel scrollable;
private HashMap<String, JButton> items;
public static void main(String[] args) {
new GUI();
}
public GUI(){
td = new ToDo();
frame = new JFrame();
t = new Thread(this);
t.start();
frame.setMinimumSize(new Dimension(480, 640));
frame.setLayout(null);
frame.setVisible(true);
contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
topPane = new JPanel();
topPane.setLayout(new GridLayout(1, 3));
topPane.setPreferredSize(new Dimension(480, 40));
main = new JButton("View Tasks");
main.setFont(new Font("Sans Serif", Font.PLAIN, fontsize));
add = new JButton("Add Task");
add.setFont(new Font("Sans Serif", Font.PLAIN, fontsize));
settings = new JButton("Settings");
settings.setFont(new Font("Sans Serif", Font.PLAIN, fontsize));
topPane.add(main);
topPane.add(add);
topPane.add(settings);
contentPane.add(topPane, BorderLayout.NORTH);
centerPane = new JPanel();
centerPane.setPreferredSize(new Dimension(480, 600));
items = new HashMap<>();
HashMap<String, Assignment> assignments = td.getAssignments();
scrollable = new JPanel();
scrollable.setLayout(new GridLayout(assignments.size(), 1));
centerScroll = new JScrollPane(scrollable);
for(String key: assignments.keySet()){
Assignment a = assignments.get(key);
JButton button = new JButton(a.getTitle() + " | " + a.getDetails() + " | " + a.getClassification().getCls() + " | " + a.getStatus().getStatus());
button.addActionListener(this);
items.put(key, button);
scrollable.add(button);
}
centerPane.add(centerScroll);
contentPane.add(centerPane, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public void update(int i){
HashMap<String, Assignment> assignments = td.getAssignments();
scrollable.removeAll();
scrollable.setLayout(new GridLayout(assignments.size(), 1));
for(String key: assignments.keySet()){
Assignment a = assignments.get(key);
JButton button = new JButton(Integer.toString(i));
button.addActionListener(this);
items.put(key, button);
scrollable.add(button);
}
scrollable.revalidate();
frame.repaint();
}
#Override
public void run(){
int counter = 0;
try {
while (true) {
update(counter);
t.sleep( 1000 ); // interval given in milliseconds
counter++;
}
}
catch (Exception e) {
System.out.println();
}
}
#Override
public void actionPerformed(ActionEvent e){
for(String s: items.keySet()){
if(items.get(s) == e.getSource()){
EventMenu em = new EventMenu(td, s);
}
}
}
}
The problem is that the buttons are not updating. I expect that the JPanel should be constantly repopulating with updated JButtons with different text, but it seems that the program hangs and doesn't update.
I tried making a simpler example which I modified from here, with different results:
public class DigitalWatch implements Runnable{
JFrame f;
JPanel p;
Thread t=null;
int hours=0, minutes=0, seconds=0;
String timeString = "";
JButton b;
DigitalWatch(){
f=new JFrame();
p = new JPanel();
t = new Thread(this);
t.start();
b=new JButton();
b.setBounds(100,100,100,50);
p.add(b);
f.add(p);
f.setSize(300,400);
f.setLayout(null);
f.setVisible(true);
}
public void run() {
try {
while (true) {
Calendar cal = Calendar.getInstance();
hours = cal.get( Calendar.HOUR_OF_DAY );
if ( hours > 12 ) hours -= 12;
minutes = cal.get( Calendar.MINUTE );
seconds = cal.get( Calendar.SECOND );
SimpleDateFormat formatter = new SimpleDateFormat("hh:mm:ss");
Date date = cal.getTime();
timeString = formatter.format( date );
p.removeAll();
b=new JButton(timeString);
b.setBounds(100,100,100,50);
p.add(b);
f.add(p);
p.revalidate();
f.repaint();
//printTime();
t.sleep( 1000 ); // interval given in milliseconds
}
}
catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
new DigitalWatch();
}
}
This snippet fails to draw anything, unlike the first which at least draws the objects created in the constructor.
How can I make a list or grid JPanel update procedurally and in real time and populate buttons? I know I could change the text of each button every time, but the number of buttons may change at any time.
Full code here.
you are violating Swing's single thread rule - you are not supposed to do any UI related stuff outside Swing's event dispatch thread.
Read up on it here and here.
Below is a working example. Not sure why they chose to use a button to show the time though. :-)
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;
public class DigitalWatch extends JFrame {
private DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
public DigitalWatch() {
JButton btn = new JButton(getCurrentTime());
this.getContentPane().setLayout(new FlowLayout());
this.getContentPane().add(btn);
this.setPreferredSize(new Dimension(200, 150));
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null); // center it on the screen
new Timer(500, e -> btn.setText(getCurrentTime())).start();
}
private String getCurrentTime() {
return formatter.format(LocalTime.now());
}
public static void main(String[] args) {
new DigitalWatch().setVisible(true);
}
}

Getting user input and then printing new text using AWT

I am trying to create a simple program where when I press a button, new text will appear but I have no idea how to do it (I imagine it is very simple).
The code I have right now is:
import java.awt.*;
public class ConsumptionGUI extends Frame
{
public ConsumptionGUI()
{
Frame fr = new Frame();
Button b1 = new Button ("Terminate Program");
Button b2 = new Button ("Start");
b1.setBounds(50,50,50,50);
b2.setBounds(50,50,50,50);
b1.addActionListener(e-> System.exit(0));
Label txt = new Label ("This is my first GUI");
//add to frame (after all buttons and text was added)
fr.add(b2);
fr.add(txt);
fr.add(b1);
fr.setSize(500,300);
fr.setTitle("Vehicles Information System");
fr.setLayout(new FlowLayout());
fr.setVisible(true);
} //end constructor
public static void main(String args[]){
ConsumptionGUI frame1= new ConsumptionGUI();
} //end main
Basically after this point I managed to create a frame with 2 buttons and some text in the middle.
I am really struggling to continue from here.
I need the program to first start by the press of a button then print some new text (something like "please enter your car's speed") and then save this information (to be used in a simple formula).
Afterwards the program needs to display the formula used and print what is the value calculated.
Can anyone please help?
Thanks
To get user input, you can implement a Dialog like in below code. You can use another similar dialog to show the formula and result as well.
import java.awt.*;
import java.awt.event.*;
public class ConsumptionGUI extends Frame
{
public ConsumptionGUI()
{
Frame fr = new Frame();
Button b1 = new Button("Terminate Program");
Button b2 = new Button("Start");
//b1.setBounds(50, 50, 50, 50); // Unnecessary
//b2.setBounds(50, 50, 50, 50); // Unnecessary
b1.addActionListener(e -> System.exit(0));
b2.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
InputDialog dialog = new InputDialog(fr);
dialog.setVisible(true);
System.out.println("User inputted speed = " + dialog.getSpeed());
}
});
Label txt = new Label("This is my first GUI");
//add to frame (after all buttons and text was added)
fr.add(b2);
fr.add(txt);
fr.add(b1);
fr.setSize(500, 300);
fr.setTitle("Vehicles Information System");
fr.setLayout(new FlowLayout());
fr.setVisible(true);
} //end constructor
public static void main(String args[])
{
ConsumptionGUI frame1 = new ConsumptionGUI();
} //end main
}
class InputDialog extends Dialog
{
private int speed;
InputDialog(Frame owner)
{
super(owner, "Input", true);
addWindowListener(new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent e)
{
dispose();
}
});
TextField textField = new TextField(20);
Button okButton = new Button("OK");
okButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
String speedString = textField.getText();
speed = !speedString.isEmpty() ? Integer.parseInt(speedString) : 0;
dispose();
}
});
setLayout(new GridLayout(3, 1));
add(new Label("Please enter your car's speed"));
add(textField);
add(okButton);
pack();
}
int getSpeed()
{
return speed;
}
}

Why can't I get the label to display text from the text field?

I am currently making a News Ticker kind of program that scrolls the users inputted text accross the JLabel. Currently I can get it to display the text in a String Variable. However when I try to pass textual input into the field it cause's errors. What I have so far that works is the following;
public class Scroll2 extends JPanel implements Runnable, ActionListener{
JLabel label;
JLabel prompt;
JPanel LabelPan;
JPanel panelForText;
String str= "Hello";
String text;
JFrame mainFrame;
JTextField t;
public Scroll2(){
super();
mainFrame = new JFrame();
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(new Dimension(840, 280));
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
mainFrame.setLayout(new GridLayout(0,1));
LabelPan = new JPanel();
LabelPan.isMaximumSizeSet();
LabelPan.setSize(620, 180);
label = new JLabel(str);
label.setFont(new Font("Serif", Font.PLAIN, 70));
LabelPan.add(label);
panelForText = new JPanel();
panelForText.setLayout(new GridLayout(0, 2));
prompt = new JLabel("Enter Text Here;");
panelForText.add(prompt);
t = new JTextField();
t.setSize(80, 53);
t.addActionListener(this);
panelForText.add(t);
mainFrame.add(LabelPan, BorderLayout.NORTH);
mainFrame.add(panelForText, BorderLayout.SOUTH);
Thread t = new Thread(this);
t.start();
}
public void run(){
while(true){
char c = str.charAt(0);
String rest = str.substring(1);
str = rest + c;
label.setText(str);
try{
Thread.sleep(200);
}catch(InterruptedException e){}
}
}
public void actionPerformed(ActionEvent evt) {
JTextField t = (JTextField) evt.getSource();
}
public static void main(String[] args) {
Scroll2 TextScroll = new Scroll2();
}
}
Any help would be appreciated thank you.
You never bother to update str in your actionPerformed() method:
public void actionPerformed( ActionEvent evt )
{
// JTextField t = (JTextField) evt.getSource();
str = t.getText();
}
Seriously if you took one minute to look at your code, you could have found this. Maybe proper indenting would help you read your code better.
(I'm going to ignore the multi-threading errors in the code. Read up on Swing concurrency: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/ )

Swing ProgressBar is not always updated

I want to create a basic JDialog with a progress bar, and to update the bar when some operations are done. My code is:
public class Main {
public static void main(String[] args) {
WikiReaderUI ui = new WikiReaderUI();
SwingUtilities.invokeLater(ui);
}}
and:
public class WikiReaderUI implements Runnable {
private JFrame frame;
protected Document doc;
protected JProgressBar progressBar;
protected int progress;
#Override
public void run() {
frame = new JFrame("Wiki READER");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set up the content pane.
addComponentsToPane(frame.getContentPane());
// Display the window.
frame.setSize(600, 320);
frame.setResizable(false);
frame.setVisible(true);
}
private void addComponentsToPane(Container pane) {
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
addLanguagePanel(pane);
//other panels...irelevant for my problem
addCreationPanel(pane);
}
private void addCreationPanel(Container pane) {
JPanel infoPanel = new JPanel();
infoPanel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.ipady = 5;
JButton createDoc = new JButton("Create PDF");
createDoc.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JDialog dlg = new JDialog(frame, "Progress Dialog", true);
progressBar = new JProgressBar(0, 500);
progressBar.setOpaque(true);
dlg.add(BorderLayout.CENTER, progressBar);
dlg.add(BorderLayout.NORTH, new JLabel("Progress..."));
dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dlg.setSize(300, 75);
dlg.setLocationRelativeTo(frame);
dlg.setVisible(true);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (progress < 500) {
progressBar.setValue(progress);
progress++;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
t.start();
}
});
infoPanel.add(createDoc, c);
pane.add(infoPanel);
}
When I run the program and click the createDoc button, the progress bar is not updated in the dialog, but if I close the dialog and click the button again, the progress bar is updating. I know it's something related with event dispatch thread, but I don't know how to change my code in order to always update the bar.
I've also tried with a SwingWorker, without success.
Make JDialog visible after starting the thread.
t.start();
dlg.setVisible(true);
Use Swing Timer instead of Java Timer that is more suitable with Swing application.
Read more How to Use Swing Timers

How to make the txPanel visible only after the 'enter pin ok' button has been clicked?

public class ATMgui extends JFrame implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
public static final int WIDTH = 500;
public static final int HEIGHT = 200;
private ATMbizlogic theBLU;// short for the Business Logic Unit
public JLabel totalBalanceLabel;
public JTextField withdrawTextField;
public JTextField depositTextField;
public JTextField pinTextField;
/**
* Creates a new instance of ATMgui
*/
public ATMgui() {
setTitle("ATM Transactions");
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
Container contentPane = getContentPane();
contentPane.setBackground(Color.BLACK);
contentPane.setLayout(new BorderLayout());
// Do the panel for the rest stop
JLabel start = new JLabel("Welcome To Your Account", JLabel.CENTER);
Font curFont = start.getFont();
start.setFont(new Font(curFont.getFontName(), curFont.getStyle(), 25));
start.setForeground(Color.BLUE);
start.setOpaque(true);
start.setBackground(Color.BLACK);
pinTextField = new JTextField();
JLabel pinLabel = new JLabel("Enter your PIN below:", JLabel.CENTER);
pinLabel.setForeground(Color.RED);
pinLabel.setOpaque(true);
pinLabel.setBackground(Color.WHITE);
JButton pinButton = new JButton("Enter Pin OK");
pinButton.addActionListener(this);
pinButton.setBackground(Color.red);
JPanel pinPanel = new JPanel();
pinPanel.setLayout(new GridLayout(3, 1, 100, 0));
pinPanel.add(pinLabel);
pinPanel.add(pinTextField);
pinPanel.add(pinButton);
contentPane.add(pinPanel, BorderLayout.WEST);
JPanel headingPanel = new JPanel();
headingPanel.setLayout(new GridLayout());
headingPanel.add(start);
contentPane.add(headingPanel, BorderLayout.NORTH);
// Do the panel for the amount & type of transactions
withdrawTextField = new JTextField();
JLabel withdrawLabel = new JLabel("Withdraw (0.00)", JLabel.CENTER);
withdrawLabel.setForeground(Color.RED);
withdrawLabel.setOpaque(true);
withdrawLabel.setBackground(Color.WHITE);
depositTextField = new JTextField();
JLabel depositLabel = new JLabel("Deposit (0.00)", JLabel.CENTER);
depositLabel.setForeground(Color.RED);
depositLabel.setOpaque(true);
depositLabel.setBackground(Color.WHITE);
JButton txButton = new JButton("Transactions OK");
txButton.addActionListener(this);
txButton.setBackground(Color.red);
JPanel txPanel = new JPanel();
txPanel.setLayout(new GridLayout(5, 1, 30, 0));
txPanel.add(withdrawLabel);
txPanel.add(withdrawTextField);
txPanel.add(depositLabel);
txPanel.add(depositTextField);
txPanel.add(txButton);
contentPane.add(txPanel, BorderLayout.EAST);
txPanel.setVisible(true);
totalBalanceLabel = new JLabel("Your balance after transactions: ", JLabel.CENTER);
totalBalanceLabel.setForeground(Color.BLUE);
totalBalanceLabel.setOpaque(true);
totalBalanceLabel.setBackground(Color.BLACK);
contentPane.add(totalBalanceLabel, BorderLayout.SOUTH);
theBLU = new ATMbizlogic();
}
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
// Container contentPane = getContentPane();
if (actionCommand.equals("Transactions OK")) {
try {
double deposit = Double.parseDouble(depositTextField.getText().trim());
double withdraw = Double.parseDouble(withdrawTextField.getText().trim());
theBLU.computeBalance(withdraw, deposit);
totalBalanceLabel.setText("Your balance after transactions: " + theBLU.getBalance());
} catch (ATMexception ex) {
totalBalanceLabel.setText("Error: " + ex.getMessage());
} catch (Exception ex) {
totalBalanceLabel.setText("Error in deposit or withdraw amount: " + ex.getMessage());
}
} else if (actionCommand.equals("Enter Pin OK")) {
try {
double pin = Double.parseDouble(pinTextField.getText().trim());
theBLU.checkPin(pin);
totalBalanceLabel.setText("Your balance after transactions: " + theBLU.getBalance());
} catch (ATMexception ex) {
totalBalanceLabel.setText("Error: " + ex.getMessage());
} catch (Exception ex) {
totalBalanceLabel.setText("Error in pin: " + ex.getMessage());
}
} else {
System.out.println("Error in button interface.");
}
}
public static void main(String[] args) {
ATMgui gui = new ATMgui();
gui.setVisible(true);
}
}
I don't think this is the right way to implement ActionListeners for buttons.
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
// Container contentPane = getContentPane();
if (actionCommand.equals("Transactions OK"))
else ...
}
With the if-else stamements in the method actionPerformed, your program is forced to check what listener to invoke, every time whatever button is pressed, and, in this way, your code isn't easy to edit and reuse.
Also, the GUI Container is acting like a receiver of events, then you should avoid
pinButton.addActionListener(this);
Try to implement your own inner classes for each button, like this:
JButton pinButton = new JButton("Enter Pin OK");
pinButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae){
//enter here your action
txPanel.setVisible(true);
}
});
In this way, you don't need to implement the ActionListener interface for your class, because you're implementing a inner istance of the interface for your pinButton. Check this old question of SO.
Also, you should avoid to implement all your GUI elements in your class constructor, it's better to implement the GUI in a separate method, like createAndShowGui(), and call it in the constructor, to respect the Java Swing conventions and to run the Swing components in a different thread, called Event Dispatch Thread, different from the main thread of your application. Read this question.
Then include txPanel.setVisible(false); in createAndShowGui() method.
Remember that the Swing components are not thread-safe.
Since the code pasted by you is not working, I had made a small program for you, have a look, and see what changes can you do to incorporate that in your case :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PanelTest extends JFrame
{
private JPanel eastPanel;
public PanelTest()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
Container container = getContentPane();
eastPanel = new JPanel();
eastPanel.setBackground(Color.DARK_GRAY);
JPanel westPanel = new JPanel();
westPanel.setBackground(Color.YELLOW);
JPanel centerPanel = new JPanel();
centerPanel.setBackground(Color.BLUE);
container.add(eastPanel, BorderLayout.LINE_START);
container.add(centerPanel, BorderLayout.CENTER);
container.add(westPanel, BorderLayout.LINE_END);
eastPanel.setVisible(false);
JButton showButton = new JButton("Click Me to Display EAST JPanel");
showButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
eastPanel.setVisible(true);
}
});
JButton hideButton = new JButton("Click Me to Hide EAST JPanel");
hideButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
eastPanel.setVisible(false);
}
});
container.add(hideButton, BorderLayout.PAGE_START);
container.add(showButton, BorderLayout.PAGE_END);
setSize(300, 300);
setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new PanelTest();
}
});
}
}
And from future, never use NORTH, EAST, WEST and SOUTH for BorderLayout. They have been replaced with PAGE_START, LINE_START, LINE_END and PAGE_END respectively.
A BorderLayout object has five areas. These areas are specified by the BorderLayout constants:
PAGE_START
PAGE_END
LINE_START
LINE_END
CENTER
Version note:
Before JDK release 1.4, the preferred names for the various areas were different, ranging from points of the compass (for example, BorderLayout.NORTH for the top area) to wordier versions of the constants we use in our examples. The constants our examples use are preferred because they are standard and enable programs to adjust to languages that have different orientations.
I had modified the checkPin(...) method of the ATMLogin class to return a boolean instead of void, so that inside the actionPerformed(...) method of the ATMgui class, if this thing returns true, then only to set the required JPanel to visible, else nothing is to be done.
Do check the code and see what changes you can do to make it work for your end.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ATMgui extends JFrame implements ActionListener
{
/**
*
*/
private static final long serialVersionUID = 1L;
public static final int WIDTH = 500;
public static final int HEIGHT = 200;
private ATMbizlogic theBLU;// short for the Business Logic Unit
private JPanel txPanel;
public JLabel totalBalanceLabel;
public JTextField withdrawTextField;
public JTextField depositTextField;
public JTextField pinTextField;
/**
* Creates a new instance of ATMgui
*/
public ATMgui()
{
setTitle("ATM Transactions");
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
Container contentPane = getContentPane();
contentPane.setBackground(Color.BLACK);
contentPane.setLayout(new BorderLayout());
// Do the panel for the rest stop
JLabel start = new JLabel("Welcome To Your Account", JLabel.CENTER);
Font curFont = start.getFont();
start.setFont(new Font(curFont.getFontName(), curFont.getStyle(), 25));
start.setForeground(Color.BLUE);
start.setOpaque(true);
start.setBackground(Color.BLACK);
pinTextField = new JTextField();
JLabel pinLabel = new JLabel("Enter your PIN below:", JLabel.CENTER);
pinLabel.setForeground(Color.RED);
pinLabel.setOpaque(true);
pinLabel.setBackground(Color.WHITE);
JButton pinButton = new JButton("Enter Pin OK");
pinButton.addActionListener(this);
pinButton.setBackground(Color.red);
JPanel pinPanel = new JPanel();
pinPanel.setLayout(new GridLayout(3, 1, 100, 0));
pinPanel.add(pinLabel);
pinPanel.add(pinTextField);
pinPanel.add(pinButton);
contentPane.add(pinPanel, BorderLayout.WEST);
JPanel headingPanel = new JPanel();
headingPanel.setLayout(new GridLayout());
headingPanel.add(start);
contentPane.add(headingPanel, BorderLayout.NORTH);
// Do the panel for the amount & type of transactions
withdrawTextField = new JTextField();
JLabel withdrawLabel = new JLabel("Withdraw (0.00)", JLabel.CENTER);
withdrawLabel.setForeground(Color.RED);
withdrawLabel.setOpaque(true);
withdrawLabel.setBackground(Color.WHITE);
depositTextField = new JTextField();
JLabel depositLabel = new JLabel("Deposit (0.00)", JLabel.CENTER);
depositLabel.setForeground(Color.RED);
depositLabel.setOpaque(true);
depositLabel.setBackground(Color.WHITE);
JButton txButton = new JButton("Transactions OK");
txButton.addActionListener(this);
txButton.setBackground(Color.red);
txPanel = new JPanel();
txPanel.setLayout(new GridLayout(5, 1, 30, 0));
txPanel.add(withdrawLabel);
txPanel.add(withdrawTextField);
txPanel.add(depositLabel);
txPanel.add(depositTextField);
txPanel.add(txButton);
contentPane.add(txPanel, BorderLayout.EAST);
txPanel.setVisible(false);
totalBalanceLabel = new JLabel("Your balance after transactions: ", JLabel.CENTER);
totalBalanceLabel.setForeground(Color.BLUE);
totalBalanceLabel.setOpaque(true);
totalBalanceLabel.setBackground(Color.BLACK);
contentPane.add(totalBalanceLabel, BorderLayout.SOUTH);
theBLU = new ATMbizlogic();
}
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
// Container contentPane = getContentPane();
if (actionCommand.equals("Transactions OK"))
{
try
{
double deposit = Double.parseDouble(depositTextField.getText().trim());
double withdraw = Double.parseDouble(withdrawTextField.getText().trim());
theBLU.computeBalance(withdraw, deposit);
totalBalanceLabel.setText("Your balance after transactions: " + theBLU.getBalance());
}
/*catch (ATMexception ex)
{
totalBalanceLabel.setText("Error: " + ex.getMessage());
}*/
catch (Exception ex)
{
totalBalanceLabel.setText("Error in deposit or withdraw amount: " + ex.getMessage());
}
}
else if (actionCommand.equals("Enter Pin OK"))
{
try
{
double pin = Double.parseDouble(pinTextField.getText().trim());
if(theBLU.checkPin(pin))
txPanel.setVisible(true);
totalBalanceLabel.setText("Your balance after transactions: " + theBLU.getBalance());
}
/*catch (ATMexception ex)
{
totalBalanceLabel.setText("Error: " + ex.getMessage());
}*/
catch (Exception ex)
{
totalBalanceLabel.setText("Error in pin: " + ex.getMessage());
ex.printStackTrace();
}
}
else
{
System.out.println("Error in button interface.");
}
}
public static void main(String[] args)
{
ATMgui gui = new ATMgui();
gui.setVisible(true);
}
}
class ATMbizlogic
{
private double totalBalance;
private boolean rightPinEntered;
/**
* Creates a new instance of ATMbizlogic
*/
public ATMbizlogic()
{
totalBalance = 0.0;
rightPinEntered = true;
}
public void computeBalance(double withdraw, double deposit)
//throws ATMexception
{
if(withdraw <=0)
{
System.out.println("Negative withdraw not allowed");
//throw new ATMexception("Negative withdraw not allowed");
}
if(deposit <=0)
{
System.out.println("Negative deposit not allowed");
//throw new ATMexception("Negative deposit not allowed");
}
double balance = deposit - withdraw;
totalBalance = totalBalance + balance;
}
public boolean checkPin(double pin)
//throws ATMexception
{
if(pin <=0)
{
System.out.println("Negative pin not allowed");
rightPinEntered = false;
//throw new ATMexception("Negative pin not allowed");
}
/*else if(rightPinEntered == false)
{
System.out.println("Can not take another pin");
rightPinEntered = false;
//throw new ATMexception("Can not take another pin");
}*/
else if(pin<1111 || pin>9999)
{
System.out.println("Enter a valid pin");
rightPinEntered = false;
//throw new ATMexception("Enter a valid pin");
}
else
{
rightPinEntered = true;
}
return rightPinEntered;
}
public double getBalance()
{
return totalBalance;
}
}
In the call to constructor ATMgui(), put
txPanel.setVisible(false);
and in the actionCommand.equals("Enter Pin OK") part, you can set it to true.
Is that what you want?

Categories

Resources