java Accessing global variable to another class(updating variables with actionperformed) - java

i am trying to access global variable of a class from another class the glass is giving me null value instead of enter value during action performed`
package com.audit;
public class panel extends JPanel {
String shost;
String suser;
String spass;
int sport;
public int getsport() {
return this.sport;
}
public String getshost() {
return this.shost;
}
public String getsuser() {
return this.suser;
}
public String getspass() {
return this.spass;
}
public panel(){
Dimension size = getPreferredSize();
size.width = 680;
size.height = 600;
setPreferredSize(size);
setBorder(BorderFactory.createTitledBorder("Linux Audit"));
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
JLabel labelhost = new JLabel("Host ");
JLabel labeluser = new JLabel("User name ");
JLabel labelpass = new JLabel("Password ");
JLabel labelport = new JLabel("Port ");
final JTextField host = new JTextField(15);
final JTextField user = new JTextField(15);
final JTextField pass=(JTextField)new JPasswordField(15);
final JTextField port = new JTextField(15);
final JButton start = new JButton("Start Audit");
//layout design
gc.anchor = GridBagConstraints.LINE_END;
gc.weightx = 0.5;
gc.weighty = 0.5;
gc.gridx=0;
gc.gridy=0;
add(labelhost,gc);
gc.gridx=0;
gc.gridy=1;
add(labeluser,gc);
gc.gridx=0;
gc.gridy=2;
add(labelpass,gc);
gc.gridx=0;
gc.gridy=3;
add(labelport,gc);
gc.anchor = GridBagConstraints.LINE_START;
gc.gridx=1;
gc.gridy=0;
add(host,gc);
gc.gridx=1;
gc.gridy=1;
add(user,gc);
gc.gridx=1;
gc.gridy=2;
add(pass,gc);
gc.gridx=1;
gc.gridy=3;
add(port,gc);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.weighty=10;
gc.gridx=1;
gc.gridy=4;
add(start,gc);
//startaudit action
start.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
String shost = host.getText();
String suser = user.getText();
String spass = pass.getText();
String sportb = port.getText();
int sport = Integer.parseInt(sportb);
sshConnection s = new sshConnection();
s.Connection();
/*System.out.println(shost);
System.out.println(suser);
System.out.println(spass);
System.out.println(sport);*/
}
});
}
}
in above i am trying to fetch the value of global variables
String shost;
String suser;
String spass;
int sport;
in another class
///another class
public class sshConnection {
public void Connection(){
String sshhost = new panel().getshost();
String sshuser = new panel().getsuser();
int sshport = new panel().getsport();
String sshpass = new panel().getspass();
System.out.println(sshhost);
System.out.println(sshuser);
System.out.println(sshport);
System.out.println(sshpass);
}
}
i am getting null values instead of inserted values at the time of execution.please solve the problem, i know its very basic but i m beginer.so plz help
thanks

In the panel class, shost, suser, etc., aren't set to anything until you click on the Start Audit button. But Connection constructs a 4 new panel objects. Those won't be the same panel objects that you clicked the button on. I think what you want to do is change your Connection method so that it takes a panel argument:
public void Connection(panel p){
String sshhost = p.getshost();
String sshuser = p.getsuser();
...
and change the s.Connection call inside your listener to
s.Connection (panel.this);
so that Connection knows what panel it's supposed to be working with.
Or, a better design might be to have Connection take the three strings and the integer as arguments, and not bother with getshost(), etc., at all.

You're creating multiple instances of panel in sshConnection#Connection whose fields are null.
The values from the existing instance of panel need to be used. I suggest simply pass them as parameters instead
public void performConnection(String sshHost, String sshUser, int sshPort, String sshPass){
...
}
Java Naming Conventions show that classes start with a uppercase letter, e.g. SshConnection while methods start with a lowecase letter, e.g. performConnection. Read Naming Conventions

Related

Remove label before I click in java

ı have problem about delete a empty string values like we can see in picture,
in the first time if here is empty he give a error but after that even we write some strings in that blank,its still giving the same error how can ı delete this label before the sending again How can ı fix that problem ı tried some codes but nothing worked well please help about that
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
public class ui {
public static void main(String[] args) {
uiVision();
}
public static void uiVision() {
ImageIcon eyes = new ImageIcon("a.png");
Globals.jf.setTitle("Deneme Uygulamasi");
Globals.jf.setLocation(100,200);
JLabel label1,label2,label3;
Globals.jf.getContentPane().setLayout(new FlowLayout());
JTextField isim = new JTextField(20);
JTextField soyisim = new JTextField(20);
JTextField pasaport = new JTextField(20);
JTextField mail = new JTextField(20);
JPasswordField passwordField = new JPasswordField(10);
JPasswordField passwordField2 = new JPasswordField(10);
JButton buton1 = new JButton("Send");
JButton buton2 = new JButton(eyes);
JButton buton3 = new JButton(eyes);
JButton buton4 = new JButton("!");
label1 = new JLabel("Name:");// -8
label2 = new JLabel("Surname:");// -9
label3 = new JLabel("Passaport-ID:");//+ 10
JLabel label4 = new JLabel("Mail:");// +10
JLabel label5 = new JLabel("Password:");//+10
JLabel label6 = new JLabel("Re-Password:");// +20
buton1.setBounds(170,400,150,30);
buton2.setBounds(320,190,50,30);
buton3.setBounds(320,230,50,30);
buton4.setBounds(370,230,50,30);
isim.setBounds(170,30,150,30);
soyisim.setBounds(170,70,150,30);
pasaport.setBounds(170,110,150,30);
mail.setBounds(170,150,150,30);
passwordField.setBounds(170,190,150,30);
passwordField2.setBounds(170,230,150,30);
label1.setBounds(125,30,150,30);
label2.setBounds(106,70,150,30);
label3.setBounds(90,110,150,30);
label4.setBounds(132,150,150,30);
label5.setBounds(105,190,150,30);
label6.setBounds(91,230,150,30);
Globals.jf.add(buton1);Globals.jf.add(buton2);Globals.jf.add(buton3);
Globals.jf.add(label1);Globals.jf.add(label2);Globals.jf.add(label3);Globals.jf.add(label4); Globals.jf.add(label5);Globals.jf.add(label6);
Globals.jf.add(isim);Globals.jf.add(soyisim);Globals.jf.add(pasaport);Globals.jf.add(mail);Globals.jf.add(passwordField);Globals.jf.add(passwordField2);
Globals.jf.setSize(1000,500);
buton2.addActionListener(l -> {
if ( passwordField.getEchoChar() != '\u0000' ) {
passwordField.setEchoChar('\u0000');
} else {
passwordField.setEchoChar((Character) UIManager.get("PasswordField.echoChar"));
}
});
buton3.addActionListener(l -> {
if ( passwordField2.getEchoChar() != '\u0000' ) {
passwordField2.setEchoChar('\u0000');
} else {
passwordField2.setEchoChar((Character) UIManager.get("PasswordField.echoChar"));
}
});
buton1.addActionListener(e -> {
checkEmpty(isim.getText(),label1.getText(),label1);
checkEmpty(soyisim.getText(),label2.getText(),label2);
checkEmpty(pasaport.getText(),label3.getText(),label3);
checkEmpty(mail.getText(),label4.getText(),label4);
ExitWhenLoopEnd();
Globals.globalInt = 0;
System.out.println(passwordField.getPassword());
System.out.println(passwordField2.getPassword());
Globals.clickCount++;
});
Globals.jf.setLayout(null);
Globals.jf.setVisible(true);
Globals.jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void checkEmpty(String value,String label,JLabel labelname) {
Integer syc = Integer.valueOf(0);
if(value != null && !value.trim().isEmpty()) {
if(Globals.globalInt != 4) {
Globals.globalInt++;
}
syc = 1;
}
else {
CreateEmptyMessageError(label,labelname,Globals.jf);
syc = -1;
}
System.out.println(syc);
}
public static void CreateEmptyMessageError(String labelError,JLabel label,JFrame jf) {
Globals.labelx = new JLabel(labelError.split(":")[0]+" is empty!");
Globals.labelx.setBounds(label.getBounds().x+250,label.getBounds().y,label.getWidth(),label.getHeight());
Globals.labelx.setForeground(Color.RED);
jf.add(Globals.labelx);
jf.revalidate();
jf.repaint();
}
public class Globals {
public static int globalInt = 0;
public static JLabel labelx = null;
public static JFrame jf = new JFrame();
public static int clickCount = 0;
public static int lastVal = 0;
public static int syc = 0;
}
public static void ExitWhenLoopEnd() {
if(Globals.globalInt == 4) {
System.exit(0);
}
}
}
Your problem is that you're creating a new JLabel and adding it to the GUI each time CreateEmptyMessageError(...) is called, and by doing this, you have no reference to this object, and no way to change its state.
The solution is to not do this, to instead create the error message label when you create the GUI itself, assign it to an instance field, and in that method above to not create a new JLabel object but rather to set the text of the existing object, one that shows a warning if the JTextField is empty, and one that sets the JLabel text to the empty String, "", if the JTextField has text.
Also,
As Progman has suggested in comments, avoid the use of static fields and methods unless the use suggests that these should be used, and this isn't the case here. Instead, use private instance fields and methods. This will make your code easier to mock/test/extend and re-use, this reduces potential for hard to identify bugs by reducing your code's cyclomatic complexity and coupling.
Avoid the use of null layouts and setBounds(...) and instead learn and use the layout managers.
Learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
Give your fields names that describe what they represent, making your code self-commenting and easier to understand.

How to add text and delete text using GUI in Java

I am creating a dumb phone (like old traditional phone) and I'm using GUI programming. I need help with dialing the numbers. I don't know how to get the numbers to pop up on the display and stay there, and also use the delete button to delete the numbers that is up on the display too. I will post a youtube link so you can see a sample run.
I am currently stuck on passing the text from the button of each number that should display the number, however it's displaying the text of the button. I also, don't know how to keep the number there when other buttons are pressed without it being reset.
Here is my code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import javax.swing.*;
public class DumbPhone extends JFrame
{
private static final long serialVersionUID = 1L;
private static final int WIDTH = 300;
private static final int HEIGHT = 500;
private static final String CALL_BUTTON_TEXT = "Call";
private static final String TEXT_BUTTON_TEXT = "Text";
private static final String DELETE_BUTTON_TEXT = "Delete";
private static final String CANCEL_BUTTON_TEXT = "Cancel";
private static final String SEND_BUTTON_TEXT = "Send";
private static final String END_BUTTON_TEXT = "End";
private static final String CALLING_DISPLAY_TEXT = "Calling...";
private static final String TEXT_DISPLAY_TEXT = "Enter text...";
private static final String ENTER_NUMBER_TEXT = "Enter a number...";
private JTextArea display;
private JButton topMiddleButton;
private JButton topLeftButton;
private JButton topRightButton;
private JButton[] numberButtons;
private JButton starButton;
private JButton poundButton;
private boolean isNumberMode = true;
private String lastPressed = "";
private int lastCharacterIndex = 0;
private Date lastPressTime;
public DumbPhone()
{
setTitle("Dumb Phone");
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(EXIT_ON_CLOSE);
createContents();
setVisible(true);
topLeftButton.setEnabled(false);
}
private void createContents()
{
//create JPanel, and JTextArea display
JPanel panel = new JPanel(new GridLayout(5,3));
display = new JTextArea();
display.setPreferredSize(new Dimension(280, 80));
display.setFont(new Font("Helvetica", Font.PLAIN, 32));
display.setLineWrap(true);
display.setEnabled(false);
panel.add(display);
//create JButtons
topLeftButton = new JButton(DELETE_BUTTON_TEXT);
topMiddleButton = new JButton((CALL_BUTTON_TEXT));
topRightButton = new JButton((TEXT_BUTTON_TEXT));
numberButtons = new JButton[10];
numberButtons[1] = new JButton("<html><center>1<br></center></html>");
numberButtons[2] = new JButton("<html><center>2<br>ABC</center></html>");
numberButtons[3] = new JButton("<html><right>3<br>DEF</right></html>");
numberButtons[4] = new JButton("<html><center>4<br>GHI</center></html>");
numberButtons[5] = new JButton("<html><center>5<br>JKL</center></html>");
numberButtons[6] = new JButton("<html><center>6<br>MNO</center></html>");
numberButtons[7] = new JButton("<html><center>7<br>PQRS</center></html>");
numberButtons[8] = new JButton("<html><center>8<br>TUV</center></html>");
numberButtons[9] = new JButton("<html><center>9<br>WXYZ</center></html>");
numberButtons[0] = new JButton("<html><center>0<br>space</center></html>");
poundButton = new JButton("#");
starButton = new JButton("*");
//add JButtons to buttons JPanel
panel.add(topLeftButton);
panel.add(topMiddleButton);
panel.add(topRightButton);
panel.add(numberButtons[1]);
panel.add(numberButtons[2]);
panel.add(numberButtons[3]);
panel.add(numberButtons[4]);
panel.add(numberButtons[5]);
panel.add(numberButtons[6]);
panel.add(numberButtons[7]);
panel.add(numberButtons[8]);
panel.add(numberButtons[9]);
panel.add(starButton);
panel.add(numberButtons[0]);
panel.add(poundButton);
//add Listener instance (inner class) to buttons
topLeftButton.addActionListener(new Listener());
topMiddleButton.addActionListener(new Listener());
topRightButton.addActionListener(new Listener());
//JButton[] array = new JButton[10];
for (int i = 0; i < numberButtons.length; i++)
{
numberButtons[i].addActionListener(new Listener());
numberButtons[i] = new JButton(String.valueOf(i));
}
starButton.addActionListener(new Listener());
poundButton.addActionListener(new Listener());
//add display and buttons to JFrame
setLayout(new BorderLayout());
add(display, BorderLayout.NORTH);
add(panel, BorderLayout.CENTER);
}
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == topLeftButton)
{
if(lastPressTime == null)
{
display.setText(ENTER_NUMBER_TEXT);
}
else
{
topLeftButton.setEnabled(true);
lastCharacterIndex--;
lastPressed = lastPressTime.toString();
}
}
else if(e.getSource() == topMiddleButton)
{
if(lastPressTime == null || lastCharacterIndex == 0)
{
display.setText(ENTER_NUMBER_TEXT);
}
else
{
display.setText(CALLING_DISPLAY_TEXT);
}
}
else if(e.getSource() == topRightButton)
{
if(lastPressTime == null || lastCharacterIndex == 0)
{
display.setText(TEXT_DISPLAY_TEXT);
}
else
{
display.setText(CALLING_DISPLAY_TEXT);
}
}
else
{
topLeftButton.setEnabled(true);
if (e.getSource() instanceof JButton)
{
//String text = ((JButton) e.getSource()).getText();
display.setText(lastPressed + " f" + numberButtons[lastCharacterIndex].getText());
}
}
Date currentPress = new Date();
long currentTime = currentPress.getTime();
if(lastPressTime != null)
{
//long lastPressTime = lastPressTime.getTime();
//subtract lastPressTime from currentPress time to find amount of time elapsed since last button pressed.
}
lastPressTime = currentPress;
String buttonLetters = ""; // Parse Letter from button (e.g "abc").
//update lastCharacterIndex.
lastCharacterIndex++;
lastCharacterIndex = lastCharacterIndex % buttonLetters.length();
}
}
for example, if I push the button 2, instead of giving me "2", it will give me < html>< center>2ABC < / center >< / html >
Therefore, I need help with
Having the numberButtons, when pushed to show the numbers that were pushed.
Be able to delete those numbers.
Here is the link to the sample run: https://www.youtube.com/watch?v=evmGWlMSqqg&feature=youtu.be
Try starting the video 20 seconds in.
to delete the number, you can use the labelname.setText("")
At a basic level, you simply want to maintain the "numbers" separately from the UI. This commonly known as a "model". The model lives independently of the UI and allows the model to be represented in any number of possible ways based on the needs of the application.
In your case, you could use a linked list, array or some other simple sequential based list, but the easiest is probably to use a StringBuilder, as it provides the functionality you require (append and remove) and can make a String very simply.
So, the first thing you need to do is create an instance of model as an instance level field;
private StringBuilder numbers = new StringBuilder(10);
this will allow the buffer to be accessed any where within the instance of the class.
Then you need to update the model...
else
{
topLeftButton.setEnabled(true);
if (e.getSource() instanceof JButton)
{
String text = numberButtons[lastCharacterIndex].getText();
numbers.append(text);
}
}
To remove the last character you can simply use something like...
if (numbers.length() > 0) {
numbers.deleteCharAt(numbers.length() - 1);
}
Then, when you need to, you update the UI using something like...
display.setText(numbers.toString());
Now, this is just basic concepts, you will need to take the ideas and apply it to your code base

Leaking this in construcor - then java.lang.NullPointerException

I've two classes, one that is responsible for "drawing" the graphics interface (MainFrame class) and another one that is a form that should be added to a panel.
When I run the code I get java.lang.NullPointerException
Here is the stack trace:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at view.MainFrame2.addModuleToLeftPanel(MainFrame2.java:213)
at view.modules.PingPong.<init>(PingPong.java:179)
at view.MainFrame2.<init>(MainFrame2.java:65)
at view.MainFrame2.<init>(MainFrame2.java:37)
at view.MainFrame2$3.run(MainFrame2.java:224)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:682)
at java.awt.EventQueue$3.run(EventQueue.java:680)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:691)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
Here is the method in my MainFrame class:
public void addModuleToLeftPanel(String tittle, Component module)
{
leftTabbedPane.add(tittle, module);
}
And leftTabbedPane is a JTabbedPane()
My other class where I call this method from MainFrame is:
public PingPong(final Api api, MainFrame2 mainFrame) {
(...)
mainFrame.addModuleToLeftPanel("Test", this); // here I get Leaking this in construcor warning.
}
I understand that the null pointer exception is because I'm adding an object that has not been initialized, right? My question is, how can I fix this problem?
What I want is to let PingPong class tell MainFrame "Hey, add me to the left panel" and MainFrame adds PingPong to the left panel.
----------------------- EDIT ------------------------
As requested, here is the code from MainFrame2 class and PingPong class:
MainFrame2.class:
public class MainFrame2 extends JFrame {
// Classes in this project
private ToolBar2 toolBar;
private Api api;
private StatusPanel2 statusPanel;
private JMenuBar menuBar;
// Modules go here
private PingPong pingPong;
// Class variables
private JTabbedPane leftTabbedPane;
private JTabbedPane rightTabbedPane;
private JSplitPane splitPane;
private MainFrame2() {
super("An awesome piece of software");
// Classes Initialization
api = Api.getInstance();
toolBar = new ToolBar2(api);
statusPanel = StatusPanel2.getInstance();
// Module classes initialization
pingPong = new PingPong(api, this);
// Java Imported Classes Initialization
leftTabbedPane = new JTabbedPane();
rightTabbedPane = new JTabbedPane();
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftTabbedPane, rightTabbedPane);
// JSplitPanel properties, make is one click expandable.
splitPane.setOneTouchExpandable(true);
// Window properties
setExtendedState(JFrame.MAXIMIZED_BOTH);//start as maximized
setVisible(true);
setMinimumSize(new Dimension(600, 400));
// Do nothing because there is a window closing listener that handles it
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
// Set Layout Manager
setLayout(new BorderLayout());
// Rezise the textPanel, otherwise by default it is just one line height
statusPanel.setPreferredSize(new Dimension(getWidth(), 150));
statusPanel.revalidate(); //Apply the changes.
/*
* To disconnect to the MySQL server when closing
* the program window
*/
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
try {
api.disconnet();
dispose(); //clean garbage collector
System.gc(); //clean garbage collector
} catch (SQLException ex) {
Logger.getLogger(MainFrame2.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
// Add the components
add(toolBar, BorderLayout.NORTH);
add(statusPanel, BorderLayout.SOUTH);
add(splitPane, BorderLayout.CENTER);
//Set the Menu
setJMenuBar(createMenuBar());
}
/*
* *************************************************************
* ----------------------- Menu Section ------------------------
* *************************************************************
*/
private JMenuBar createMenuBar() {
menuBar = new JMenuBar();
JMenu editMenu = new JMenu("Edit");
JMenu fileMenu = new JMenu("File");
JMenu windowMenu = new JMenu("Window");
JCheckBoxMenuItem showDataProcessForm = new JCheckBoxMenuItem("Show Data Input Panel");
showDataProcessForm.setSelected(true);
JMenuItem showSourceServerForm = new JMenuItem("Configure Source Server");
JMenuItem showDestinationServerForm = new JMenuItem("Configure Destination Server");
JMenuItem optionsDialogForm = new JMenuItem("Options");
editMenu.add(showSourceServerForm);
editMenu.add(showDestinationServerForm);
editMenu.add(optionsDialogForm);
windowMenu.add(showDataProcessForm);
JMenuItem importResults = new JMenuItem("Import Results");
JMenuItem exportResults = new JMenuItem("Export Results");
JMenuItem importDatabase = new JMenuItem("Import Table to the Database");
JMenuItem exportDatabaseTable = new JMenuItem("Export Table from the Database");
JMenuItem quitItem = new JMenuItem("Quit");
fileMenu.add(importResults);
fileMenu.add(exportResults);
fileMenu.addSeparator();
fileMenu.add(importDatabase);
fileMenu.add(exportDatabaseTable);
fileMenu.addSeparator();
fileMenu.add(quitItem);
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(windowMenu);
// Creating Mnemonics
fileMenu.setMnemonic(KeyEvent.VK_F);//VK_F stands for virtual key, alt+F
editMenu.setMnemonic(KeyEvent.VK_E); // alt + E
windowMenu.setMnemonic(KeyEvent.VK_W); // alt + W
// showSourceServerForm.setMnemonic(KeyEvent.VK_S); // alt + s
// showDestinationServerForm.setMnemonic(KeyEvent.VK_D); // alt + d
// Creating accelerators, control + s -> save file
quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK));
importResults.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, ActionEvent.CTRL_MASK));
exportResults.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, ActionEvent.CTRL_MASK));
showSourceServerForm.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
showDestinationServerForm.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, ActionEvent.CTRL_MASK));
/*
* Adding Action Listener
*/
quitItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int action = JOptionPane.showConfirmDialog(MainFrame2.this, "Do you really want to quit the application?", "Confirm Exit", JOptionPane.OK_CANCEL_OPTION);
if (action == JOptionPane.OK_OPTION) {
WindowListener[] listeners = getWindowListeners();
for (WindowListener listener : listeners) {
listener.windowClosing(new WindowEvent(MainFrame2.this, 0));
}
}
}
});
return menuBar;
}
public void addModuleToLeftPanel(String tittle, Component module)
{
leftTabbedPane.add(tittle, module);
}
// Main
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MainFrame2();
}
});
}
}
PingPong.class:
public class PingPong extends JPanel {
private JLabel readFromLabel;
private JLabel accessSessionTimeThresholdLabelLabel;
private JLabel transitionTimeThresholdLabelLabel;
private JLabel smoothLabel;
private JLabel statisticsLabel;
private JTextField accessSessionTimeThresholdField;
private JTextField transitionTimeThresholdField;
private JTextField writeToNewTableField;
private JComboBox readFromComboBox;
private JComboBox writeToTableComboBox;
private JRadioButton writeResultsToNewTableRadio;
private JRadioButton writeResultsToExistingTableRadio;
private ButtonGroup writeResultsToTableGroup;
private JCheckBox smoothCheckBox;
private JCheckBox statisticsCheckBox;
private JButton applyButton;
private JButton refreshReadDataFrom;
private JButton refreshSaveDataTo;
private String[] itemsComboBox;
public PingPong(final Api api, MainFrame2 mainFrame)
{
Border innerBorder = BorderFactory.createTitledBorder("Detect Ping Pong");
Border outterBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5);
setBorder(BorderFactory.createCompoundBorder(outterBorder, innerBorder));
Dimension dim = new Dimension(400, 100);
setPreferredSize(dim);
setMinimumSize(dim);
// Labels
readFromLabel = new JLabel("Read Data From: ");
writeResultsToExistingTableRadio = new JRadioButton("Save Results to Existing Table: ");
writeResultsToNewTableRadio = new JRadioButton("Save Results to New Table: ");
accessSessionTimeThresholdLabelLabel = new JLabel("Access Session Time Threshold: ");
transitionTimeThresholdLabelLabel = new JLabel("Transition Time Threshold: ");
smoothLabel = new JLabel("Smooth Ping Pong?");
statisticsLabel = new JLabel("Output Ping Pong statistics?");
// JTextFields
accessSessionTimeThresholdField = new JTextField(5);
transitionTimeThresholdField = new JTextField(5);
writeToNewTableField = new JTextField(10);
// JCheckBox
smoothCheckBox = new JCheckBox();
statisticsCheckBox = new JCheckBox();
itemsComboBox = new String[] {"Not Connected"};
readFromComboBox = new JComboBox(itemsComboBox);
writeToTableComboBox = new JComboBox(itemsComboBox);
// JButton
applyButton = new JButton("Apply");
refreshReadDataFrom = new JButton();
refreshReadDataFrom.setIcon(createIcon("/view/images/view-refresh.png"));
refreshReadDataFrom.setToolTipText("Refresh the current table list.");
refreshSaveDataTo = new JButton();
refreshSaveDataTo.setIcon(createIcon("/view/images/view-refresh.png"));
refreshSaveDataTo.setToolTipText("Refresh the current table list.");
writeResultsToTableGroup = new ButtonGroup();
writeResultsToTableGroup.add(writeResultsToExistingTableRadio);
writeResultsToTableGroup.add(writeResultsToNewTableRadio);
// Adding a listener to the Apply JButton
applyButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Get the database table to where save the results
String writeToTable = "";
String sessionThreshold = accessSessionTimeThresholdField.getText();
String transitionThreshold = transitionTimeThresholdField.getText();
String readFromTable = readFromComboBox.getSelectedItem().toString();
boolean smoothPingPong = smoothCheckBox.isSelected();
boolean statistics = smoothCheckBox.isSelected();
boolean newTable = writeResultsToNewTableRadio.isSelected();
if(writeResultsToExistingTableRadio.isSelected())
{
writeToTable = writeToTableComboBox.getSelectedItem().toString();
}
if(writeResultsToNewTableRadio.isSelected())
{
writeToTable = writeToNewTableField.getText();
}
// Validate the form
if(writeToTable.isEmpty() | sessionThreshold == null | transitionThreshold.isEmpty() | readFromTable.isEmpty() )
{
JOptionPane.showMessageDialog(null, "Please double check the input data "
+ "in the Ping Pong form. Select a radio buttom and/or insert the required data.", "Ping Pong Form Error",
JOptionPane.ERROR_MESSAGE);
return;
}
// To do...
}
});
// Adding a listener to the refresh JButton
refreshReadDataFrom.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
// api.showTables(api.getConnectionSourceServer());
String[] items = {"Testing 1", "Testing 2"};
api.setCombomBoxNewItemList(items, readFromComboBox);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Please make sure you are connected to the server"
, "Connection Error",
JOptionPane.ERROR_MESSAGE);
}
}
});
// Adding a listener to the refresh JButton
refreshSaveDataTo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
api.showTables(api.getConnectionDestinationServer());
} catch (Exception ex) {
api.displayErrorBox(ex.getMessage(), "Connection Error!");
}
}
});
layoutComponents();
mainFrame.addModuleToLeftPanel("Teste", this);
}
public void layoutComponents()
{
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints(); //class that specifies where goes what we want
////////// Insert and Align Labels and Fields //////////
gc.fill = GridBagConstraints.NONE;
// Specify to which side it will stick to
gc.anchor = GridBagConstraints.WEST; // stick to the left hand side
// how much space it takes relatively to other cells, on the X axis.
gc.weighty = 2;
// how much space it takes relatively to other cells, on the Y axis.
gc.weightx = 8;
gc.gridx = 0;
gc.gridy = 1;
add(readFromLabel, gc);
gc.gridx = 1;
add(readFromComboBox, gc);
gc.gridx = 2;
add(refreshReadDataFrom, gc);
gc.gridy = 2;
gc.gridx = 0;
add(writeResultsToNewTableRadio, gc);
gc.gridx = 1;
add(writeToNewTableField, gc);
gc.gridy = 3;
gc.gridx = 0;
add(writeResultsToExistingTableRadio, gc);
gc.gridx = 1;
add(writeToTableComboBox, gc);
gc.gridx = 2;
add(refreshSaveDataTo, gc);
gc.gridy = 4;
gc.gridx = 0;
add(accessSessionTimeThresholdLabelLabel, gc);
gc.gridx = 1;
add(accessSessionTimeThresholdField, gc);
gc.gridy = 5;
gc.gridx = 0;
add(transitionTimeThresholdLabelLabel, gc);
gc.gridx = 1;
add(transitionTimeThresholdField, gc);
gc.gridy = 6;
gc.gridx = 0;
add(smoothLabel, gc);
gc.gridx = 1;
add(smoothCheckBox, gc);
gc.gridy = 7;
gc.gridx = 0;
add(statisticsLabel, gc);
gc.gridx = 1;
add(statisticsCheckBox, gc);
gc.weighty = 15;
gc.anchor = GridBagConstraints.NORTHWEST;
gc.gridy = 8;
add(applyButton, gc);
}
// Should this method be in the API? I think so...
private ImageIcon createIcon(String path)
{
URL url = getClass().getResource(path);
if(url == null)
{
System.err.println("Could not load the icon: " + path);
}
ImageIcon icon = new ImageIcon(url);
return icon;
}
}
You have created a nice cyclic dependency. A MainFrame2 needs a PingPong which needs a MainFrame2 again. That's generally something you should avoid because it causes exactly problems like yours. Leaking this in the constructor is a good indication that you may have done that. It's not always a problem, especially if the other class just stores the reference for later.
The easy fix in your case should be moving the creation of PingPong after that part that initializes the fields that are required.
If you want to get rid of your dependency problem you need to break the cycle. Two options exist: Create PingPong without reference to MainFrame, then give it to MainFrame's constructor. Or the other way: create MainFrame first, then give it to PingPong's constructor.
For a simple implementation you could use a static factory method.
class MainFrame2 {
private MainFrame2() {
super("An awesome piece of software");
// etc.. no modules added here
}
public static MainFrame2 newInstance() {
MainFrame2 result = new MainFrame2();
new PingPong(api, result);
// alternatively something like:
// result.addModuleToLeftPanel("Teste", new PingPong(api))
// add more here
result.updateTheLayoutBecauseThereAreNewModules();
return result;
}
}
class User {
public static void main(String[] args) {
MainFrame2 frame = MainFrame2.newInstance();
// instead of: new MainFrame2();
}
}
Now if you want to solve the problem that adding modules requires changes of MainFrame2 you can expand the factory pattern to use a registry of modules that adds modules without need to know details about the modules.
public class MainFrame2 extends JFrame {
/** An interface that abstracts creation of a "Module" */
public interface ModuleFactory {
public String getTitle();
public Component createModule(Api api);
}
/** A Place to register modules */
public static enum ModuleRegistry {
INSTANCE;
private final List<ModuleFactory> leftModules = new ArrayList<ModuleFactory>();
public void registerModuleForLeftPanel(ModuleFactory factory) {
leftModules.add(factory);
}
private void addModulesTo(MainFrame2 mainFrame2, Api api) {
for (ModuleFactory factory : leftModules) {
mainFrame2.addModuleToLeftPanel(factory.getTitle(), factory.createModule(api));
}
}
}
/** Creates an instance of MainFrame2 with all registered modules */
public static MainFrame2 newInstance() {
MainFrame2 result = new MainFrame2();
ModuleRegistry.INSTANCE.addModulesTo(result, result.api);
return result;
}
// ...
}
Nothing needs to touch MainFrame2 now. You could distribute it as a library and people could add modules like below.
class User {
public static void main(String[] args) {
// static bootstrap code - needs to be run once at the beginning - can be anywhere
// if you want to add modules you can do it here
MainFrame2.ModuleRegistry.INSTANCE.registerModuleForLeftPanel(new ModuleFactory() {
#Override
public String getTitle() {
return "Teste";
}
#Override
public Component createModule(Api api) {
return new PingPong(api);
}
});
// create a mainframe
MainFrame2.newInstance();
}
}
You could in theory put the registration part into each module (in a static { } initializer block) but that causes another problem: The class needs to be loaded in order have a chance to execute code and that's not going to happen if nothing loads that class explicitly.

Modifying an item in an arraylist coding issue

I am trying to change values of items in my arraylist. I can't seem to get this working. I am at a loss as to how to really ask this question. The code is quite extensive (or at least it is in my book) so I can't really show all of it. However if I know the current index, how can I make it change the ItemName?
currentIndex.setItemName(newItemName);
CurrentIndex is an int that tells me which index I am at, ItemName is a string that is in my arraylist. Should I be getting the ItemName prior to trying to set it? Something like this
InventoryItem.getItemName();
currentIndex.setItemName(newItemName);
This also does not work.
Edit: I was asked to show more code. Here is the panel that pops up in my action listener
modifyButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JTextField xField = new JTextField(15);
JTextField yField = new JTextField(15);
JTextField zField = new JTextField(15);
JPanel myPanel = new JPanel();
myPanel.add(new JLabel("Item Name:"));
myPanel.add(xField);
myPanel.add(Box.createVerticalStrut(15)); // a spacer
myPanel.add(new JLabel("Number in inventory:"));
myPanel.add(yField);
myPanel.add(Box.createVerticalStrut(15)); // a spacer
myPanel.add(new JLabel("Unit Price:"));
myPanel.add(zField);
int result = JOptionPane.showConfirmDialog(null, myPanel,
"Please Enter data into all boxes", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
String newItemName = String.valueOf(xField);
String text1 = yField.getText();
String newInventoryAmount = String.valueOf(text1);
int newAmount = Integer.parseInt(newInventoryAmount);
String text2 = zField.getText();
String newUnitPrice = String.valueOf(text2);
double newPrice = Double.parseDouble(newUnitPrice);
inventory.get(currentIndex).setItemName(newItemName);
inventory.get(currentIndex).setInStock(newAmount);
inventory.get(currentIndex).setUnitPrice(newPrice);
}
}
}
);
I'm not sure what your ArrayList is name so I'll just call it arrayList.
Try
arrayList.get(currentIndex).setItemName(newItemName);
arrayList.get(currentIndex) calls the element from your list at the current index
That allows you to use .setItemName(newItemName) to change the name of the object.
ìnt doesn't have a method setItemName (or any method at all, since it's a primitive, not an object).
Try yourArrayList.get(currentIndex).setItemName(newItemName);
It calls setItemName on the desired element of the list.
EDIT: to fix your new problem, replace String newItemName = String.valueOf(xField); with
String newItemName = xField.getText();
I believe this is what you want to do.
list.set(index, newItemName)
http://docs.oracle.com/javase/7/docs/api/java/util/List.html#set(int, E)
Check out this code that accomplishes what I think you are trying to do.
public class Test {
public static void main(String args[]){
ArrayList<Employee> myArrayList = new ArrayList<Employee>();
Employee e1 = new Employee();
e1.setName("Juan");
myArrayList.add(e1);
myArrayList.get(0).setName("Jhon");
System.out.println(myArrayList.get(0).getName());
}
}
class Employee {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

How to validate a JTextField?

How to validate a textfield to enter only 4 digits after the decimal point in Swing?
Any validation in Swing can be performed using an InputVerifier.
1. First create your own input verifier:
public class MyInputVerifier extends InputVerifier {
#Override
public boolean verify(JComponent input) {
String text = ((JTextField) input).getText();
try {
BigDecimal value = new BigDecimal(text);
return (value.scale() <= Math.abs(4));
} catch (NumberFormatException e) {
return false;
}
}
}
2. Then assign an instance of that class to your text field. (In fact any JComponent can be verified)
myTextField.setInputVerifier(new MyInputVerifier());
Of course you can also use an anonymous inner class, but if the validator is to be used on other components, too, a normal class is better.
Also have a look at the SDK documentation: JComponent#setInputVerifier.
You could probably accomplish the same with DocumentListener. All you have to do is validate the input string against the desired string pattern. In this case, the pattern seems to be one or more digits, followed by a period, AND exactly 4 digits after the decimal point. The code below demonstrates using DocumentListener to accomplish this:
public class Dummy
{
private static JTextField field = new JTextField(10);
private static JLabel errorMsg = new JLabel("Invalid input");
private static String pattern = "\\d+\\.\\d{4}";
private static JFrame frame = new JFrame();
private static JPanel panel = new JPanel();
public static void main(String[] args)
{
errorMsg.setForeground(Color.RED);
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(5, 0, 0, 5);
c.gridx = 1;
c.gridy = 0;
c.anchor = GridBagConstraints.SOUTH;
panel.add(errorMsg, c);
c.gridx = 1;
c.gridy = 1;
c.anchor = GridBagConstraints.CENTER;
panel.add(field, c);
frame.getContentPane().add(panel);
field.getDocument().addDocumentListener(new DocumentListener()
{
#Override
public void removeUpdate(DocumentEvent e)
{
validateInput();
}
#Override
public void insertUpdate(DocumentEvent e)
{
validateInput();
}
#Override
public void changedUpdate(DocumentEvent e) {} // Not needed for plain-text fields
});
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static void validateInput()
{
String text = field.getText();
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(text);
if (m.matches())
{
errorMsg.setForeground(frame.getBackground());
}
else
{
errorMsg.setForeground(Color.RED);
}
}
}
As long as the text field does not contain a valid input, the error message is shown like the image below.
Once the input is validated, the error message will not be visible.
Of course, you can replace the validation action to whatever you need. For example, you may want to display some popup when a button is clicked if the input is not valid, etc.
I threw this together to show an alternative to answer given already. There might be cases when this solution might be more suitable. There might be cases when the given answer might be more suitable. But one thing is certain, alternatives are always a good thing.

Categories