java - get content that appears to be layered from another class - java

I am trying to make a simple GUI word dragging game and the way I structured the code is that I have a Driver class that sets up the main JFrame and a JPanel where the words are to be contained in and a JButton that prompts a Popup class to ask for a new word to add. and then creates a WordBox. My problem seems to arise from the fact that the Popup class is a sub-class (I think thats the correct term) and so it seems that there seems to be an extra Popup class as a layer between the Driver and the actual Popup with the WordBox. I know its confusing, but here is some of the code:
public class Popup extends JFrame implements ActionListener {
JLabel lblPrompt;
JTextField txtWord;
JButton btnOK;
BoxWord w;
static BoxWord word;
public Popup(){
//window formatting was here
btnOK.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e){
w = new BoxWord(txtWord.getText());
//word = new BoxWord("it works");
}
public static void main(String[] args) {
Popup p = new Popup();
//System.out.println(word.getWord());
}
and
public class BoxWord extends JButton {
private String s = "";
public BoxWord(String word){
this.s = word;
this.setText(word);
}
public String getWord(){
return s;
}
}
and the Driver:
public class Driver extends JFrame implements ActionListener{
JButton addWord;
JPanel panel;
int x, y;
public Driver(){
//Window formatting was here
addWord.addActionListener(this);
}
public static void main(String[] args) {
Driver d = new Driver();
}
#Override
public void actionPerformed(ActionEvent e){//make a new popup to ask for word
Popup p = new Popup();
BoxWord w = p.w;
System.out.println(w.getWord());
w.setLocation(100,100);
}
My error is (at least the begining of it. the whole thing is like 20 lines long):
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at worddrag.Driver.actionPerformed(Driver.java:42)
The line 42 is the
System.out.println(w.getWord());
I feel this is a very trivial and simple problem but I cannot figure out why I keep getting the error. I essentially need to be able to access the BoxWord in the Popup actionPerformed method from the Popup main method. any and all help is appreciated. My apologies for the wall of text

w is obviously null when you try to access it.
Your problem is that you're using a JFrame where a modal dialog or JOptionPane would work better. If you used the dialog, then your calling code would wait until the dialog is no longer visible, and at that time, w would likely no longer be null.
Edit
You ask:
and can you elaborate on why JFrame will not work? Just telling me that its my problem doesnt help very much -
What? I didn't just tell you that it was the problem -- I offered a solution -- use a modal JDialog. Again, a modal dialog will freeze code flow from the calling code when it is launched, and the calling code will remain frozen until the dialog is no longer visible.
Your problem is that your attempting to use the w variable before the dialog window has had a chance to do anything with it. A JFrame does not pause the calling code's program flow, and that is causing your problem.
Edit 2
So a JFrame doesn't actually execute the code until it is closed?
No, not true at all. Look where your w is given a valid reference -- in your JFrame's button's ActionListener. So w will not receive a valid reference until the ActionListener has been called, which only will happen when the button is pressed. Your code as written tries to use w immediately before the user has had any chance to push your pop-up's buttons. If you used a modal JDialog instead, and made sure that w was set prior to closing the dialog, your code could work.
But a JDialog will do so as it gets the input?
Nope. See above.

Related

JFrame appears blank after swapping JFrames twice (using Intellij GUI designer)

I'm relatively new to Java Swing in general and decided to use Intellij's GUI Designer. For those not familiar with it, Intellij creates 2 files for each GUI "screen". One is the "design" in the form of a .form file where you drag and drop UI components, and one is the "controller".
Anyway, I'm doing a 5-step questionnaire implemented on Java Swing. The first part asks the user what is their favourite fruit, and when a choice button is clicked, the choice is saved and the next JFrame appears with the next question and so on. JFrame1 transitioning to JFrame2 worked fine, and all UI components were shown. However, when I tried to transition from JFrame2 to JFrame3, JFrame3 showed up blank instead.
I've tried to call .pack() before setVisible(true), and then calling .toFront() after that, but that didn't help.
Below shows a section of my code. JFrame1, 2, and 3 all use the same exact code in its constructors and calling of the next JFrame. JFrame1 only differs by a single line which will be stated later in the code.
JFrame1.java
public class Frame1 extends JFrame {
private JPanel mainPanel;
private JLabel narrationLabel;
private JButton option1_btn;
private JButton option2_btn;
private JButton option3_btn;
public Frame1()
{
setTitle("Questionnaire");
setSize(1000, 1000);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Frame2 nextScreen = new Frame2 (); //declare the next screen to show
add(mainPanel); //this is only for the first starting JFrame
//JFrame2 and JFrame3 do not have this
//repeat this for buttons option2_btn and option3_btn
option1_btn.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
//swap screens to the next main filler selection screen
mainPanel.setVisible(false);
nextScreen.pack();
add(nextScreen.getPanel());
nextScreen.getPanel().setVisible(true);
}
});
}
public JPanel getPanel()
{
return mainPanel;
}
}
Main.java
public class Main
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame1 frame1 = new JFrame1(); //create start screen GUI
frame1.setVisible(true); //display GUI
}
});
}
}
My hunch tells me it might a concurrency issue, but I'm not sure if I am right, or where is the issue and how to resolve it. If a .form file is needed, I would gladly upload the code for it. Any help appreciated.

Passing parameter from textfield in on one jframe to another jframe

I'm trying to simply create four jtextfields and a jbutton. Once the button is pushed, i want the text inputted into the jtextfields to be passed as parameters (p, var, s, f) to another window to which displays a mathematical function using the parameters given.
I don't want this second window to show up and display a mathematical function until the initial button was pushed.
How can I do this? I'm sorry if this is a newbie question but I'm learning..
So far, I have graphing part done, and so all I need to do now is create the first window with the textboxes and buttons which link to the graphing window.
Here is the beginning of the code that I think is worth showing so you know which variables I'm talking about:
public class Cartesian {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
CartesianFrame frame = new CartesianFrame();
frame.showUI();
}
});
}
}
class CartesianFrame extends JFrame {
CartesianPanel panel;
public CartesianFrame() {
panel = new CartesianPanel();
add(panel);
}
public void showUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Polynomial Grapher");
setSize(700, 700);
setVisible(true);
}
}
class CartesianPanel extends JPanel {
//These are the variables I want to be assigned to textfields(I'm assuming using "gettext" from another window.
String p="something from textbox one";//Variable 1
String var="something from textbox two";//Variable 2
double s=-2;//ANY double value from textbox 3
double f=2;//ANY double value from textbox 4
...
...
...
The rest of the code used after this is just a paint component, etc. which is used to display the cartesian plane and the mathematical function.
I've looked on the web for some other examples, but they haven't applied to what I'm doing.. I'm interested in any feedback! Thank you!
Don't create a second JFrame. If you absolutely must show a second window, show a dialog such as a JDialog or JOptionPane. As to how to do this, simply create a JPanel that displays the information that you'd like to show the user, perhaps in a JLabel, and then show it in a JOptionPane using its showMessage(...) method. It's pretty easy, actually.
If this doesn't help, then you'd better tell us more about exactly where you're stuck.

how to call active frame that already exist from another class that extends JDialog then remove all of its component?

I have class main extends jframe, it has a button that calls /shows another class that extends jdialog.
If the button from jdialog is triggered, it will dispose that dialog and will remove all component of jframe, then add it to a new jpanel.
What should I do?
Here's my new broken code:
public class mainz extends JFrame{
mainz(){
setVisible(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JToolBar r = new JToolBar();
r.add(Box.createHorizontalGlue());
add(r, BorderLayout.NORTH);
JButton n = new JButton();
r.add(n, BorderLayout.EAST);
n.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
show();
}
});
}
public void show(){
dialogz d = new dialogz(this);
d.setVisible(true);
}
public void lastHope(){
getContentPane().removeAll();
getContentPane().validate();
getContentPane().repaint();
}
public static void main (String[]args){
new mainz().setExtendedState(MAXIMIZED_BOTH);
}
}
public class dialogz extends JDialog{
public dialogz(final mainz owner) {
setSize(300, 300);
JButton n = new JButton("execute");
add(n);
final JFrame ew = (JFrame)super.getOwner();// <<
n.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
dispose();
//owner.lastHope;
ew.removeAll();// <<
ew.validate();// <<
ew.repaint();// <<
}
});
}
void yes(){
getOwner().removeAll();
getOwner().validate();
getOwner().repaint();
}
}
I know I can prevent my main class from extending jframe, and call it from main instead, but I want to do it like that...
Please help me ... T-T
Sorry for my English, I from a far away country ~,~"
update:
the error is
java.lang.ClassCastException: javax.swing.SwingUtilities$SharedOwnerFrame cannot be cast to javax.swing.JFrame
it will be done with delete the line that contain
// <<
then call lastHope();
but i think there's a another way to get that existing jframe to removeall
(by casting it first or something ~,~" )
You are calling getParent() but you never set the parent (or owner). That should happen in the constructor as already pointed out. Also, be mindful that getParent() returns a Container object and getOwner() returns a Window object. Both of these refer to the JFrame which is the parent and owner. If you want to use it as a JFrame, you'll have to cast the output as (JFrame). But removeAll() is in Container class so if that's all you want, there'll be no need for casting.
Update:
JFrame frame = new JFrame();
JDialog dialog = new JDialog(frame);//frame is owner
JFrame parentOfDialog = (JFrame)(dialog.getParent());
//OR
//JFrame parentOfDialog = (JFrame)(dialog.getOwner());
parentOfDialog.removeAll();
If you are using your custom class, pass JFrame in the constructor and call super.
Please read the javadoc on JDialog before you try to use it. Also, read more about inheritance.
I'm not clear on what your goal is, but if you want to change the components that are displayed in a container, such as a JFrame or JDialog's contentPane, then I recommend that you use a CardLayout to do this since it allows you to easily swap "views".
There could be two ways to do this:
Your JDialog class could use a reference to the JFrame that is passed in via its constructor (and you should then pass it immediately into the dialog's super constructor so that your modality will work correctly). You could then call any public methods in the JFrame's class.
Or since the JDialog is modal, the JFrame's code will halt while the dialog is visible. You could swap "views" immediately after the dialog has been disposed of and is no longer visible. this would keep the JFrame manipulating code in the JFrame class.
Edit: note that if you don't use CardLayout, then you're responsible for calling revalidate() and repaint() on any container who gets its components changed.
As an aside: since English is not your first tongue and nor is it the native language of many folks on this forum, please avoid using non-standard abbreviations. The clearer your communication with us, the easier it will be for us to understand you and help you.

Closing the Main JFrame

I have a main jFrame with the help of which i press button and open new JFrames but the problem is that when i open other JFrame the previous ones still remains there where as what i want is that when i press next button then i move forward to the new JFrame (the previous one should not be there) and when i press previous button i move back to the previous JFrame.
I know there are functions of dispose,they do well like jframe1.dispose() but i dont get it how to hide the very first JFrame whose code in the main is written like this
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run()
{
new GraphicalInterface().setVisible(true);
}
});
}
how do i set this as .setVisible(false) in the button code?
You need to retain a reference to the JFrame, so you can set it's visibility later.
private JFrame myFrame;
public void run() {
myFrame = new GUI();
myFrame.setVisible(true);
}
public void hide() {
myFrame.setVisible(false);
}
Note that a JFrame is a top-level container, you are only really supposed to have one per application. It may be better if instead of using multiple JFrames you use just one, and swap in various JPanels instead.
It would safe resources if you keep just one frame and set a new panel as content.
Your question was how to handle the reference to the frame? Please provide the code where the next frame is created.
You could assign your GUI (extends JFrame I suppose) to a variable and call .setVisible(false) on that object. Since your object from the code above is more or less anonymous, you won't have access on that.
You could also check this.

Text in Label not displaying correctly with setText method

I'm trying to set the text in a label dynamically by calling the setText method whenever a button is clicked. Here is my code:
import java.awt.*;
import java.awt.event.*;
class Date {
public static void main(String[] args) {
new MainWindow();
}
}
class MainWindow {
static Label month = new Label();
static Label day = new Label();
static Button submit = new Button("Submit");
MainWindow() {
Frame myFrame = new Frame("Date Window");
myFrame.setLayout(new FlowLayout());
myFrame.add(month);
myFrame.add(day);
myFrame.add(submit);
submit.addActionListener(new ButtonListener());
myFrame.addWindowListener(new WindowListener());
myFrame.setSize(200, 200);
myFrame.setVisible(true);
}
}
class WindowListener extends WindowAdapter {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == MainWindow.submit) {
MainWindow.month.setText("12");
MainWindow.day.setText("31");
}
}
}
When I initialize the two Label objects without any arguments, the strings "12" and "31" that are passed to the setText method aren't visible on the screen when the submit button is clicked until I click on the window and drag to resize it. I've noticed this on a Mac only. On a PC, the strings are are visible but obscured until I resize the window. However, if I initialize the labels like this:
static Label month = new Label("0");
static Label day = new Label("0");
On the Mac, the strings appear as intended, however, they're obscured until the window is resized. What am I missing?
Calling validate() on the Frame as mentioned here solved the problem.
Try repainting the frame or/and set enough space(setPreferredSize, setMininumSize)
Well, most of your posting are over a year old so I'll give you the benefit of the doubt. I never use AWT so I don't know what the problem is, but I'll suggest:
1) Name you classes properly. "Date" is already a class in the JDK. Choose a better name.
2) Try using Swing components instead of AWT.
3) Get rid of static variables from your class.
4) Get rid of the WindowListener to close the frame.
The code example you posted here is 10-15 years old. Try something newer. Start with the Swing tutorial for more recent examples.

Categories