How get data from JFrame Component Java? - 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();;
}
});
}

Related

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

JSliders only sliding halfway

I have a number JSliders in my application and I'm wondering as to why they only slide to half way.
public class test1 extends javax.swing.JFrame {
public test1() {
initComponents();
jSlider1.setExtent(255);
jSlider1.setValue(-255);
}
#SuppressWarnings("unchecked")
private void initComponents() {
jSlider1 = new javax.swing.JSlider();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new test().setVisible(true);
}
});
}
private javax.swing.JSlider jSlider1;
}
Using setExtent or setMaximum would seem to work the same but setExtent makes it so that the slider only slides half way. The proper code looks like this:
public class test1 extends javax.swing.JFrame {
public test1() {
initComponents();
jSlider1.setMaximum(255);
jSlider1.setValue(-255);
}
#SuppressWarnings("unchecked")
private void initComponents() {
jSlider1 = new javax.swing.JSlider();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new test().setVisible(true);
}
});
}
private javax.swing.JSlider jSlider1;
}
You should set jslider1.setMinimum(-255) and jslider1.setMaximum(255) if your intention is to create range from -255 to 255.
You can also implement ChangeListener interface and use addChangeListener to add the listener to the slider. You can do something in the method stateChanged(ChangeEvent e) e.g. updating the RGB color.

JFrame in separate class, what about the ActionListener?

I'm trying to separate my Swing GUI from my actual code. In short, I want the user to kick off a process (based on the user's selections); in this case, the JFrame will no longer be needed.
What I couldn't figure out is how to share the user's selection from the GUI.class with the Main.class.
Do you have any advice for me?
Here's my code:
public class Main {
public static void main(String[] args) {
// Show GUI
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
GUI gui = new GUI(templates);
gui.setVisible(true);
}
});
// Kick off a process based on the user's selection
}
}
public class GUI extends JFrame {
private static final long serialVersionUID = 1L;
public GUI(Object[] objects) {
setTitle("GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 350, 100);
setLocationRelativeTo(null);
JPanel cp = new JPanel();
cp.setBorder(new EmptyBorder(10, 10, 10, 10));
setContentPane(cp);
JLabel lbl = new JLabel("Selection:");
cp.add(lbl);
final JComboBox<String> comboBox = new JComboBox<String>(new String[] { "One", "Two", "Three" });
comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
// Share the selected item with Main.class
}
});
cp.add(comboBox);
}
}
You could create an object to store the selection result and pass it in to the constructor of the GUI class. Set the selection result in that object before closing the UI and then your Main class could access the value:
public class SelectionResult {
private String selectionResult;
public void setSelectionResult(final String selectionResult) {
this.selectionResult = selectionResult;
}
public String getSelectionResult() {
return this.selectionResult;
}
}
Then, you could modify the GUI constructor like this:
private final SelectionResult selectionResult;
public GUI(Object[] objects, SelectionResult selectionResult) {
this.selectionResult = selectionResult;
...
Create a SelectionResult object in your Main class, and pass it to the constructor of the GUI class. In you GUI class ActionListener, you can then call the setSelectionResult() method with the selected value and that value will be available from the Main class.
You would need to add code to make your main method wait while you are waiting for the value to be set in the UI and then proceed with your logic based on the selection.
A Good way of doing this is use Callback mechanism.
Steps to follow:
create a callback interface
interface Callback {
void execute(Object result);
}
GUI class will implement Callback interface but without providing any implementation
Make GUI class abstract
abstract class GUI extends JFrame implements Callback
Now create an object of GUI class providing actual implementation of Callback interface
Here you can use Anonymous class
GUI gui = new GUI() {
#Override
public void execute(Object result) {
System.out.println("You have selected " + result);
}
};
You can pass any thing in execute() method of Callback.
comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
// Share the selected item with Main.class
// Callback
execute(comboBox.getSelectedItem());
}
});
Here Main class is responsible for capturing the response of Callback that is directed by GUI class.
Here is the code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
// Show GUI
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
GUI gui = new GUI() {
#Override
public void execute(Object result) {
System.out.println("You have selected " + result);
}
};
gui.setVisible(true);
}
});
// Kick off a process based on the user's selection
}
}
interface Callback {
void execute(Object result);
}
abstract class GUI extends JFrame implements Callback {
private static final long serialVersionUID = 1L;
public GUI() {
setTitle("GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 350, 100);
setLocationRelativeTo(null);
JPanel cp = new JPanel();
cp.setBorder(new EmptyBorder(10, 10, 10, 10));
setContentPane(cp);
JLabel lbl = new JLabel("Selection:");
cp.add(lbl);
final JComboBox comboBox = new JComboBox(new String[] { "One", "Two", "Three" });
comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
// Share the selected item with Main.class
execute(comboBox.getSelectedItem());
}
});
cp.add(comboBox);
}
}

Making a mouse button trigger a class event

I am really struggling with making a program that has buttons on it and when a button is clicked, it calls a class to work. I have only been using Java for about 10 weeks now and I get the basics but I have not found any place that gives me an understanding of what I want to do here.
I have tried
public void mouseEntered(MouseEvent e) {
if (e.getButton()== MouseEvent.BUTTON3){
Object triangle;
Frame.class.getClass();
}
}
I have also tried
panel.addMouseListener(new MouseAdapter() {
if (e.getButton()== MouseEvent.BUTTON1) {
Frame.class.getClass(circle); }
Either way I have tried it I usually get an error unable to find object or The method getClass() in the type Objectis not applicable for the arguments (JButton).
Can anyone please help me try to figure out what I am doing wrong?
Thank you.
public class MainFrame extends JFrame {
private JButton button = new JButton("Run AnotherClass");
MainFrame() {
super();
this.setTitle("Demo App");
this.setSize(200,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
this.add(button);
button.addActionListener(new ButtonHandler());
}
public class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
new AnotherClass();
}
}
public static void main(String[] args) {
new MainFrame().setVisible(true);
}
}
public class AnotherClass {
public AnotherClass() {
JOptionPane.showMessageDialog(null, "AnotherClass is in operation");
}
}

How to quit or exit slave JWindow that was created from a master JWindow in Java?

How can i exit only they new MainGame that i created from Main?
Where Main is having an original layer of game. And the MainGame was a dialog window (such as modal windows).
Main.java: (main code)
public class Main extends JWindow
{
private static JWindow j;
public static MainGame mp;
public static void main(String[] args)
{
new Thread(new Runnable()
{
public void run()
{
mp = new MainGame();
mp.runit();
//mp.stopit();
}
}).start();
j = new Main();
j.setVisible(true);
}
}
MainGame.java: (this was extended by Main, and i would like to quite this only).
public class MainGame extends JWindow
{
private static JWindow j;
public MainGame()
{
// some GUI ...
}
public static void runit()
{
j = new MainGame();
j.setVisible();
}
}
1) better would be implements CardLayout, as create Top-Level Container for new Window, then you'll only to switch betweens Cards
2) don't create lots of Top-Level Container on Runtime, because there are still in JVM memory untill current instance exist,
create required number of and re-use that, to avoiding possible memory lacks
then you have to call setVisible(false) and setVisible(true)
JWindow missed methods for setting setDefaultCloseOperation(Whatever);
3) if you'll create constructor public JWindow(Frame owner), then you'll call directly
SwingUtilities.getAccessibleChildrenCount() and SwingUtilities.getWindowAncestor()
import javax.swing.*;
import java.awt.*;
public class Testing {
private JFrame f = new JFrame("Main Frame");
private JWindow splashScreen = new JWindow();
public Testing() {
splashScreen = new JWindow(f);
splashScreen.getContentPane().setLayout(new GridBagLayout());
JLabel label = new JLabel("Splash Screen");
label.setFont(label.getFont().deriveFont(96f));
splashScreen.getContentPane().add(label, new GridBagConstraints());
splashScreen.pack();
splashScreen.setLocationRelativeTo(null);
splashScreen.setVisible(true);
new Thread(new Runnable() {
#Override
public void run() {
readDatabase();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
}).start();
}
public void readDatabase() {
//simulate time to read/load data - 10 seconds?
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
public void createAndShowGUI() {
JLabel label = new JLabel("My Frame");
label.setFont(label.getFont().deriveFont(96f));
f.add(label);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
System.out.println("JFrame getAccessibleChildrenCount count -> "
+ SwingUtilities.getAccessibleChildrenCount(f));
System.out.println("JWindow getParent -> "
+ SwingUtilities.getWindowAncestor(splashScreen));
splashScreen.dispose();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Testing t = new Testing();
}
});
}
}
I did not go really into your design. but there is 'j.dispose();'.
this should work. here is the java documentation.
notice:
dispose(); - deletes the window from memory.
setVisibilty(false); - just hides it from the screen.
You can override the 'dispose()' function to do some stuff while the widow is closing (updating scores if its a game) but at the end of the overriden function you have to call 'super.dispose();' so the function of the class Window is called.
And the MainGame was a dialog window
But thats not what your code uses. You use a JWindow.
You should be using a JDialog for a modal window. Then you just dispose() the window.

Categories