Pass static class reference to a constructor of non-static class - java

I need to have a reference to the Client because I need to invoke a setWinTitle to change the title of current window. How to fix it?
public class Client {
public static void main(String[] args){
JPanel gui= startGUI();
...
}
private static JPanel startGUI(){
f = new JFrame();
JPanel gui = new JPanel(this); // error
}
public void setWinTitle(String tite){
f.setTitle(tite);
}
}
public class JPanel extends javax.swing.JPanel {
Client client;
public JPanel(Client cl) {
client= cl;
initComponents();
}
...
}

You need to create an instance of Client:
JPanel gui = new JPanel(new Client());

Related

How get data from JFrame Component Java?

I need get some data from "Board" Component but i dont know how. I tried Frame.Component.data but is doesn't work.
Code:
public class window extends JFrame {
public window() {
add(new Board());
setResizable(true);
pack();
setTitle("Game");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame ex = new window();
ex.setVisible(true);
ex.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
//ex.Board.data
System.exit(0);
}
});
});
}}
First a little tip to have a quick answer : reduced your code at the minimun to reproduced your bug its easier to understand especially in your case where your real purpose is in a comment ... and then make it compilable ...
To answer to your issue : personnaly i use dedicated fields to have a direct link to object i want to handle later there is two reason first a field is easy to use and don't use lot of memory . Second this solution will not depend on the way your frame is organised. an other way to get the same result is the second snippet the probelme is that if you change your frame organisation you will have to modify your listener
package so1;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Window extends JFrame {
private static final long serialVersionUID = 3000003489937872937L;
public class Data {
public void doSomethings() {
System.out.println("toto");
}
}
public class Board extends JLabel {
private static final long serialVersionUID = 7362684018638848838L;
private Data data = new Data();
}
private Board board;
public Window() {
board = new Board();
add(board);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
public static void main(String[] args) {
Window ex = new Window();
ex.setVisible(true);
ex.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
ex.board.data.doSomethings();
}
});
}
}
the bad solution :
public static void main(String[] args) {
Window ex = new Window();
ex.setVisible(true);
ex.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
((Board)((JPanel)((JLayeredPane)((JRootPane)ex.getComponents()[0]).getComponents()[1]).getComponents()[0]).getComponents()[0]).data.doSomethings();;
}
});
}

Pass user input (from TextField) to another class?

I have the following problem: I have 2 classes in my game - CONFIGUREGAME (CG) and ROULETTETABLE (RT) - and the user is able to specify details about the game like his name or his money in the class CG. In the class RT I want the input from a JTextField from the class CG to be shown on a button in class RT.
Here's my code (I simplified it alot):
public class CONFIGUREGAME extends JFrame implements ActionListener
{
Jframe frame = new JFrame("...");
public JTextField playername1 = new JTextField();
public JButton startgame = new JButton();
public CONFIGUREGAME()
{
startgame.addActionListener(this);
}
public static void main(String (String[] args)
{
new CONFIGUREGAME();
}
public void actionPerformed(ActionEvent aEvt)
{
if(aEvt.getSource()==startgame)
{
frame.dispose();
new ROULETTETABLE();
}
}
now Class 2:
import ...;
public class ROULETTETABLE extends CONFIGUREGAME implements ActionListener
{
public player1 = new JButton();
public ROULETTETABLE()
{
String Strplayername1 = playername1.getText();
player1.setText(Strplayername1);
}
public static void main(String (String[] args)
{
new ROULETTETABLE();
}
}
I tried various ways that were supposed to help but they didn't. My UI is working totally fine so if there's a mistake in it it's because I made a mistake simplifying it.
I appreciate any from of help!
You need something like this.
public class CONFIGUREGAME extends JFrame implements ActionListener
{
Jframe frame = new JFrame("...");
public JTextField playername1 = new JTextField();
public JButton startgame = new JButton();
public CONFIGUREGAME()
{
startgame.addActionListener(this);
}
public static void main(String (String[] args)
{
new CONFIGUREGAME();
}
public void actionPerformed(ActionEvent aEvt)
{
if(aEvt.getSource()==startgame)
{
frame.dispose();
new ROULETTETABLE(playername1.getText());
}
}
}
public class ROULETTETABLE extends CONFIGUREGAME implements ActionListener
{
public JButton player1 = new JButton();
public ROULETTETABLE(String playerName)
{
player1.setText(playerName);
}
public static void main(String (String[] args)
{
new ROULETTETABLE();
}
}
P.S. Please learn the Java method and class notation. CapitalizedClassName, firstWordLowercaseMethodName, firstWordLowercaseVariableName, UPPER_CASE_CONSTANT_NAME
Option #1
Pass the result CONFIGUREGAME to ROULETTETABLE
public class CONFIGUREGAME extends JFrame implements ActionListener {
//Jframe frame = new JFrame("..."); WHY?
//...
public void actionPerformed(ActionEvent aEvt) {
if (aEvt.getSource() == startgame) {
frame.dispose();
new ROULETTETABLE(playername1.getText());
}
}
public class ROULETTETABLE extends JFrame /* CONFIGUREGAME why? */implements ActionListener
{
public JButton player1 = new JButton();
public ROULETTETABLE(String playerName)
{
player1.setText(playerName);
}
}
I'm not a fan of this because it couples of the CONFIGUREGAME class to the ROULETTETABLE
A Better Option...
Use a JDialog to collect the configuration information and then pass it to the ROULETTETABLE class
First, some reconfiguration of the classes. As a general rule, avoid extending from top level classes like JFrame, they couple the code to single access point and reduce it's flexibility and re-use
public class Roulettetable extends JPanel implements ActionListener {
private JButton player1 = new JButton();
public Roulettetable(String name) {
player1.setText(name);
}
}
public class ConfigureGame extends JPanel {
private JTextField playername1 = new JTextField();
public ConfigureGame() {
}
public String getPlayerName() {
return playername1.getText();
}
}
Then you wrap it altogether...
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
ConfigureGame configureGame = new ConfigureGame();
JOptionPane.showOptionDialog(null, configureGame, "Configure Game", JOptionPane.OK_OPTION, JOptionPane.PLAIN_MESSAGE, null, new Object[] {"Start"}, 0);
String name = configureGame.getPlayerName();
Roulettetable roulettetable = new Roulettetable(name);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(roulettetable);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
This example is pretty simple, it simply makes use of JOptionPane to display the dialog.
Have a look at How to Make Dialogs for more details

I have two classes and want to get a variable from one to the other

I have two classes. Draw and DrawGUI. In DrawGUI I have a JPanel. For my JUnit test I need to ask the class Draw for getWidth() and getHeight(). So my code is like the following:
public class Draw {
public static void main(String[] args) throws ColorException {new Draw();}
/** Application constructor: create an instance of our GUI class */
public Draw() throws ColorException { window = new DrawGUI(this); }
protected JFrame window;
public void getWidth(){
}
}
class DrawGUI extends JFrame {
JPanel drawPanel;
public DrawGUI(Draw application) throws ColorException {
super("Draw"); // Create the window
app = application;
drawPanel = new JPanel();
}
}
So how do I implement getWidth? getWidth should return the width from the JPanel drawPanel
One option is to change the weak type you're saving your window under:
public class Draw {
public static void main(String[] args) throws ColorException {new Draw();}
/** Application constructor: create an instance of our GUI class */
public Draw() throws ColorException { window = new DrawGUI(this); }
protected DrawGUI window; // <- is now a DrawGUI
public int getWidth(){
return window.getPanelWidth();
}
}
class DrawGUI extends JFrame {
JPanel drawPanel;
...
public DrawGUI(Draw application) throws ColorException {
super("Draw"); // Create the window
app = application;
drawPanel = new JPanel();
}
public int getPanelWidth() { // <- added method to get panel width
return drawPanel.getWidth();
}
}
There are other options. You could also just make a getter for the whole panel, but then you have less encapsulation.

Java, changing active card for another class

Looking at other answers, i have followed exactly what they say, but i just keep getting the nullPointerException error. I have 4 classes, the 2 below, a GUI class and main menu class. Main manages the card layout and i would like a button in the Insert class to change the "Active" card to main menu class.
Main:
public class Main extends JPanel implements ChooserListener{
MainMenu mm;
Insert InsertCustomer;
public JPanel mPanel;
CardLayout cl;
private String c;
public Main(){
super();
//add mPanel, set to CardLayout and add the Main
mPanel = new JPanel();
this.add(mPanel);
cl = new CardLayout();
mPanel.setLayout(cl);
//add classes
mm = new MainMenu(this);
InsertCustomer = new Insert();
//add classes to mPanel
mPanel.add(mm, "mm");
mPanel.add(InsertCustomer, "InsertCustomer");
}
public void tell(Object o) {
c = o.toString();
cl.show(mPanel, c);
}
public void swapView(String key) {
CardLayout cl = (CardLayout)(mPanel.getLayout());
cl.show(mPanel, key);
}
}
Insert:
public class Insert extends JPanel{
private JButton logoutbutton;
private LogoutListener lListener;
public Insert() {
super();
//BUTTONS
//logout button
JButton logoutbutton = new JButton("Main Menu");
this.add(logoutbutton);
lListener = new LogoutListener(null);
logoutbutton.addActionListener(lListener);
}
private class LogoutListener implements ActionListener{
private Main main;
public LogoutListener(Main main){
this.main = main;
}
public void actionPerformed(ActionEvent e) {
main.swapView("mm");
}
}
}
lListener = new LogoutListener(null);
Your LogoutListener takes your Main-class, but you give him null. Of course you will get a NullPointerException (at least on your logoutButton-click).
Your problem in next lines :
lListener = new LogoutListener(null);
main.swapView("mm");
You need to put reference to your Main class, not null as you done. Because of your main in LogoutListener is null and you catch NPE.
Simple solution is to transfer reference of your Main to Insert with help of constructor and then transfer that to LogoutListener.

Java JTextField information access from another class

I am using a gui with JTextFields to collect some information and then a JButton that takes that infomration and writes it to a file, sets the gui visibility to false, and then uses Runnable to create an instance of another JFrame from a different class to display a slideshow.
I would like to access some of the information for the JTextFields from the new JFrame slideshow. I have tried creating an object of the previous class with accessor methods, but the values keep coming back null (I know that I have done this correctly).
I'm worried that when the accessor methods go to check what the variables equal the JTextFields appear null to the new JFrame.
Below is the sscce that shows this problem.
package accessmain;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class AccessMain extends JFrame implements ActionListener
{
private static final int FRAMEWIDTH = 800;
private static final int FRAMEHEIGHT = 300;
private JPanel mainPanel;
private PrintWriter outputStream = null;
private JTextField subjectNumberText;
private String subjectNumberString;
public static void main(String[] args)
{
AccessMain gui = new AccessMain();
gui.setVisible(true);
}
public AccessMain()
{
super("Self Paced Slideshow");
setSize(FRAMEWIDTH, FRAMEHEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
//Begin Main Content Panel
mainPanel = new JPanel();
mainPanel.setBorder(new EmptyBorder(0,10,0,10));
mainPanel.setLayout(new GridLayout(7, 2));
mainPanel.setBackground(Color.WHITE);
add(mainPanel, BorderLayout.CENTER);
mainPanel.add(new JLabel("Subject Number: "));
subjectNumberText = new JTextField(30);
mainPanel.add(subjectNumberText);
mainPanel.add(new JLabel(""));
JButton launch = new JButton("Begin Slideshow");
launch.addActionListener(this);
mainPanel.add(launch);
//End Main Content Panel
}
#Override
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
if(actionCommand.equals("Begin Slideshow"))
{
subjectNumberString = subjectNumberText.getText();
if(!(subjectNumberString.equals("")))
{
System.out.println(getSubjectNumber());
this.setVisible(false);
writeFile();
outputStream.println("Subject Number:\t" + subjectNumberString);
outputStream.close();
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
AccessClass testClass = new AccessClass();
testClass.setVisible(true);
}
});
}
else
{
//Add warning dialogue here later
}
}
}
private void writeFile()
{
try
{
outputStream = new PrintWriter(new FileOutputStream(subjectNumberString + ".txt", false));
}
catch(FileNotFoundException e)
{
System.out.println("Cannot find file " + subjectNumberString + ".txt or it could not be opened.");
System.exit(0);
}
}
public String getSubjectNumber()
{
return subjectNumberString;
}
}
And then creating a barebones class to show the loss of data:
package accessmain;
import javax.swing.*;
import java.awt.*;
public class AccessClass extends JFrame
{
AccessMain experiment = new AccessMain();
String subjectNumber = experiment.getSubjectNumber();
public AccessClass()
{
System.out.println(subjectNumber);
}
}
Hardcoding the accessor method with "test" like this:
public String getSubjectNumber()
{
return "test";
}
Running this method as below in the new JFrame:
SelfPaceMain experiment = new SelfPaceMain();
private String subjectNumber = experiment.getSubjectNumber();
System.out.println(subjectNumber);
Does cause the system to print "test". So the accessor methods seem to be working. However, trying to access the values from the JTextFields doesn't seem to work.
I would read the information from the file I create, but without being able to pass the subjectNumber (which is used as the name of the file), I can't tell the new class what file to open.
Is there a good way to pass data from JTextFields to other classes?
pass the argument 'AccessMain' or 'JTextField' to the second class:
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
AccessClass testClass = new AccessClass(AccessMain.this); //fixed this
testClass.setVisible(true);
}
});
Then reading the value of 'subjectNumber'(JTextField value) from the 'AccessMain' or 'JTextField' in the second class:
public class AccessClass extends JFrame
{
final AccessMain experiment;
public AccessClass(AccessMain experiment)
{
this.experiment = experiment;
}
public String getSubjectNumber(){
return experiment.getSubjectNumber();
}
}
Also, you should try Observer pattern.
A simple demo of Observalbe and Observer
Observable and Observer Objects

Categories