Swing components not displayed - java

This is my code and when I execute, all I get is a blank window. First when I tried to do main.setContentPane() I got this error:
"Cannot make a static reference to the non-static field panel"
So i put it in the constructor, but nothing would show.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainFrame extends JFrame{
private JPanel panel;
private JButton performance;
private JButton concordance;
private JButton discordance;
private JButton resultat;
public void MainFrame() {
panel = new JPanel(new GridLayout(4, 1, 10, 10));
performance = new JButton("performance");
concordance = new JButton("concordance");
discordance = new JButton("discordance");
resultat = new JButton("resultat");
performance.setSize(50, 30);
concordance.setSize(50, 30);
discordance.setSize(50, 30);
resultat.setSize(50, 30);
panel.add(performance);
panel.add(concordance);
panel.add(discordance);
panel.add(resultat);
getContentPane().add(panel);
}
public static void main(String[] args) {
MainFrame main = new MainFrame();
main.setSize(300, 200);
main.setDefaultCloseOperation(EXIT_ON_CLOSE);
main.setVisible(true);
}
}

You have a method (returning void) called MainFrame that is never being called.
You should either make that the constructor, or create a constructor that calls that method like so:
public class MainFrame extends JFrame {
private JPanel panel;
private JButton performance;
private JButton concordance;
private JButton discordance;
private JButton resultat;
public MainFrame() {
super();
MainFrame();
}
public void MainFrame() {
panel = new JPanel(new GridLayout(4, 1, 10, 10));
performance = new JButton("performance");
concordance = new JButton("concordance");
discordance = new JButton("discordance");
resultat = new JButton("resultat");
performance.setSize(50, 30);
concordance.setSize(50, 30);
discordance.setSize(50, 30);
resultat.setSize(50, 30);
panel.add(performance);
panel.add(concordance);
panel.add(discordance);
panel.add(resultat);
this.getContentPane().add(panel);
}
public static void main(String[] args) {
MainFrame main = new MainFrame();
main.setSize(300, 200);
main.setDefaultCloseOperation(EXIT_ON_CLOSE);
main.setVisible(true);
main.MainFrame();
}
}

Related

Selecting JFrame without using 'this' command

public main() {
initComponents();
JPanel panel=new JPanel();
panel.setBounds(0, 0, 100, 100);
panel.setBackground(Jtrue);
this.add(panel);
}
I am able to add Jframe object using this command
However, when I write this in a separate method, I cannot add because the 'this' method is inside that object.
public void created(){
int degisken=1;
JPanel panel=new JPanel();
panel.setBounds(0, 0, 100, 100);
panel.setBackground(Jtrue);
this.add(panel);
}
How can I select that jframe instead of 'this'
I don't want to create a new jframe because there is already one
You should create you JFrame instance in a way that it will be visible in your whole class.
You can achieve this by declaring a JFrame as a private member of your class. Then you will be able to access it in all class methods:
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JFrameDemo {
private JFrame frame;
public JFrameDemo() {
this.frame=new JFrame("Demo #1");
initComponents();
created();
}
private void initComponents() {
// Do your stuff here
}
public void created() {
int degisken = 1;
JPanel panel = new JPanel();
panel.setBounds(0, 0, 100, 100);
panel.setPreferredSize(new Dimension(640, 480));
panel.setBackground(new Color(255, 128, 112));
this.frame.getContentPane().add(panel);
this.frame.pack();
this.frame.setVisible(true);
}
public static void main(String[] args) {
JFrameDemo frameDemo = new JFrameDemo();
}
}
Another solution is that your class extends JFrame. This way, you will access the JFrame instance using the this keyword because this is your class and thus your JFrame:
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JFrameDemo2 extends JFrame {
public JFrameDemo2() {
super("Demo #2");
initComponents();
created();
}
private void initComponents() {
// Do your stuff here
}
public void created() {
int degisken = 1;
JPanel panel = new JPanel();
panel.setBounds(0, 0, 100, 100);
panel.setPreferredSize(new Dimension(640, 480));
panel.setBackground(new Color(255, 128, 112));
this.getContentPane().add(panel);
}
public static void main(String[] args) {
JFrameDemo2 frameDemo = new JFrameDemo2();
frameDemo.pack();
frameDemo.setVisible(true);
}
}
Another remark: don't add your component directly on your JFrame but on the underlying container:
yourFrameInstance.getContentPane().add(yourComponentInstance)

Can I communicate between two JFrames WITHOUT using static variables or methods?

Basically, I'm trying to get the JButton in Frame1 to edit the JLabel in Frame2. I know it can work if I set the JLabel and getLabel() method in Frame2 to static, and have the ActionListener reference Frame1 directly, but I want to know if there's a way to do it without using static variables or methods.
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String[] args) {
Frame2 f2 = new Frame2();
f2.pack();
f2.setLocation(700, 400);
f2.setVisible(true);
Frame1 f1 = new Frame1(f2);
f1.pack();
f1.setLocation(400, 400);
f1.setVisible(true);
}
}
class Frame1 extends JFrame {
JButton button;
public Frame1(JFrame f) {
super("Frame 1");
setDefaultCloseOperation(EXIT_ON_CLOSE);
button = new JButton("Button");
add(button);
button.addActionListener(new Listener(f.getLabel()));
}
}
class Frame2 extends JFrame {
JLabel label;
public Frame2() {
super("Frame 2");
setDefaultCloseOperation(EXIT_ON_CLOSE);
label = new JLabel("hello");
add(label);
}
public JLabel getLabel() {
return label;
}
}
class Listener implements ActionListener {
private JLabel lab;
public Listener(JLabel lab) {
this.lab = lab;
}
public void actionPerformed(ActionEvent e) {
lab.setText("nice");
}
}
Any suggestions? Thanks!
EDIT: Here's a compilable version of the code -- label and getLabel() are static, and the ActionListener references JFrame1 directly when it's called. My goal is to have no static variables or methods (outside of main).
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String[] args) {
Frame2 f2 = new Frame2();
f2.pack();
f2.setLocation(700, 400);
f2.setVisible(true);
Frame1 f1 = new Frame1(f2);
f1.pack();
f1.setLocation(400, 400);
f1.setVisible(true);
}
}
class Frame1 extends JFrame {
JButton button;
public Frame1(JFrame f) {
super("Frame 1");
setDefaultCloseOperation(EXIT_ON_CLOSE);
button = new JButton("Button");
add(button);
button.addActionListener(new Listener(Frame2.getLabel()));
}
}
class Frame2 extends JFrame {
static JLabel label;
public Frame2() {
super("Frame 2");
setDefaultCloseOperation(EXIT_ON_CLOSE);
label = new JLabel("hello");
add(label);
}
public static JLabel getLabel() {
return label;
}
}
class Listener implements ActionListener {
private JLabel lab;
public Listener(JLabel lab) {
this.lab = lab;
}
public void actionPerformed(ActionEvent e) {
lab.setText("nice");
}
}
Oracle has a really nifty Swing tutorial. I think your studying the tutorial would be a really good idea.
I had to make a bunch of changes to your code to get it to execute.
The main change I made was to keep the reference to the JLabel in the Frame2 class. I passed an instance of Frame2 to the Listener class. Just like I did yesterday with your previous question.
Here's the code. Take the time to study what I did before you ask another question tomorrow.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DoubleJFrameTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Frame2 f2 = new Frame2();
f2.pack();
f2.setLocation(700, 400);
f2.setVisible(true);
Frame1 f1 = new Frame1(f2);
f1.pack();
f1.setLocation(400, 400);
f1.setVisible(true);
}
});
}
}
class Frame1 extends JFrame {
private static final long serialVersionUID = 1L;
private JButton button;
public Frame1(Frame2 f) {
super("Frame 1");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
button = new JButton("Button");
button.addActionListener(new Listener(f));
panel.add(button, BorderLayout.CENTER);
add(panel);
}
}
class Frame2 extends JFrame {
private static final long serialVersionUID = 1L;
private JLabel label;
public Frame2() {
super("Frame 2");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
label = new JLabel("hello");
panel.add(label, BorderLayout.CENTER);
add(panel);
}
public void setLabelText(String text) {
label.setText(text);;
}
}
class Listener implements ActionListener {
private Frame2 frame;
public Listener(Frame2 frame) {
this.frame = frame;
}
#Override
public void actionPerformed(ActionEvent e) {
frame.setLabelText("nice");
}
}

Updating TextField from different class than GUI

I'm trying to update the GUI from a different Class. Every time I have tried calling the method on a different class it doesn't work but If I do it in the GUI Class it works just fine.
GUI Class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test7 extends JPanel implements ActionListener {
private JButton jcomp1;
private JButton jcomp2;
private JButton jcomp3;
private JTextField jcomp4;
public Test7() {
//construct components
jcomp1 = new JButton("Button 1");
jcomp2 = new JButton("Button 2");
jcomp3 = new JButton("Button 3");
jcomp4 = new JTextField(5);
jcomp1.addActionListener(this);
//adjust size and set layout
setPreferredSize(new Dimension(723, 455));
setLayout(null);
//add components
add(jcomp1);
add(jcomp2);
add(jcomp3);
add(jcomp4);
//set component bounds (only needed by Absolute Positioning)
jcomp1.setBounds(160, 320, 100, 20);
jcomp2.setBounds(340, 320, 100, 20);
jcomp3.setBounds(490, 315, 140, 20);
jcomp4.setBounds(180, 125, 365, 110);
}
public static void main(String[] args) {
JFrame frame = new JFrame("MyPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Test7());
frame.pack();
frame.setVisible(true);
}
public void setTextArea(JTextField jcomp4) {
this.jcomp4 = jcomp4;
}
public JTextField getTextArea() {
return this.jcomp4;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jcomp1) {
Class class1 = new Class();
class1.start();
}
}
}
Second Class:
public class Class extends Test7{
public void start(){
Test7 form = new Test7();
form.getTextArea().setText("nesto");
}
}
I have also tried putting the code on a same Thread but that doesn't seem to work either.
Test7 is JPanel. It is added to JFrame in your main method. When you call Class.start() you create new Test7. This new JPanel is not related to JPanel previously added to JFrame, so it is not even visible.
Your Class class should neither extend nor create new Test7 instance. Instead Test7 instance could be passed in constructor to Class:
Class class1 = new Class(this);
class1.start();
Your Class class:
public class Class {
private final Test7 test;
public Class(Test7 test) {
super();
this.test = test;
}
public void start() {
test.getTextArea().setText("nesto");
}
}
Andrew`s comments are also worthwile to think about.

JAVA: Save user input as a string in a Jframe GUI

Noob here. I have been browsing for hours, and I still cannot figure out the proper way to get user input to be saved as a string from a text field in my Jframe. Any help would be appreciated. I want to save the user's text into the variable userWords.
package cipher;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
public class cipherApp extends JFrame {
private static final int WIDTH = 700;
private static final int HEIGHT = 700;
private String userWords; // stores user input into a string
public cipherApp(){
setTitle("Camo Cipher");
setSize(WIDTH, HEIGHT);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args){
cipherApp newInstance = new cipherApp();
}
}
You have to use a JTextField and a JButton to submit the use input:
public class Test extends JFrame {
String userWord = "";
JTextField userInput = new JTextField(10);
JButton submit = new JButton("Submit");
public Test() {
super("Camo Cipher");
JPanel centerPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 15));
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null); // This center the window on the screen
submit.addActionListener( (e)-> {
submitAction();
});
centerPanel.add(userInput);
JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 15));
southPanel.add(submit);
Box theBox = Box.createVerticalBox();
theBox.add(Box.createVerticalStrut(100));
theBox.add(centerPanel);
theBox.add(Box.createVerticalStrut(200));
theBox.add(southPanel);
add(theBox);
}
private void submitAction() {
// You can do some validation here before assign the text to the variable
userWord = userInput.getText();
}
public static void main(String[] args) {
new Test().setVisible(true);
}
}
This is a variation of BilaDja's code (I mainly changed the graphics). This will make the window size at around half the screen, in the middle of the screen. If you would like to change the size, change the field 'jf.setSize(x, y);'.
package test;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Test extends JFrame {
private static final long serialVersionUID = -5624404136485946868L;
String userWord = "";
JTextField userInput;
public Test() {
JFrame jf = new JFrame();
JPanel panel = new JPanel();
JLabel jl = new JLabel("Test");
JButton jButton = new JButton("Click");
userInput = new JTextField("", 30);
jButton.addActionListener( (e) -> {
submitAction();
});
jf.setSize(500, 500);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(panel);
panel.add(jl);
panel.add(userInput);
panel.add(jButton);
}
private void submitAction() {
userWord = userInput.getText();
//do something with the variabe userWord here (print it to the console, etc.)
}
public static void main(String[] args) {
new Test();
}

Using JScrollBar to update Components

public class FaceMain extends JFrame {
CreateFace p1 = new CreateFace();
private ControlPanel panel;
public FaceMain(ControlPanel value) {
panel = value;
JFrame main = new JFrame();
main.setTitle("Face Frame");
main.setSize(new Dimension(600, 600));
main.setLocationRelativeTo(null);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setVisible(true);
Container c = main.getContentPane();
main.add(p1);
panel.eyesSetE(true);
JFrame control = new JFrame();
control.setTitle("Control Panel");
control.setSize(new Dimension(300, 300));
control.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
control.setLocationRelativeTo(main);
control.setVisible(true);
ControlPanel p2 = new ControlPanel(p1);
control.add(p2);
}
}
public class ControlPanel extends JPanel {
boolean eyesSetEdit = false, faceSetEdit = false, mouthSetEdit = false,
editEyes;
private Color purple = new Color(133, 22, 145);
private CreateFace face;
private CreateFace p1;
public ControlPanel(CreateFace value) {
face = value;
p1 = value;
setLayout(new GridLayout(4, 0));
JButton change = new JButton("Click");
add(change);
JLabel info = new JLabel("Click Above To Change Features",
JLabel.CENTER);
add(info);
JLabel info1 = new JLabel("Slide Below To Change Size", JLabel.CENTER);
add(info1);
JScrollBar slider = new JScrollBar(Scrollbar.HORIZONTAL, 0, 100, 0, 300);
add(slider);
public void eyesSetE(boolean x) {
eyesSetEdit = x;
}
public boolean getEyesSet() {
return eyesSetEdit;
}
I have expanded my class to try and change a boolean value which will be used exstensivly in the ControlPanel class to make decisions however everytime I start the program I get a nullpointerexception at the line "panel.eyesSetE(true);" Even if I try and call getEyesSet() I still recieve a nullpointer
You never change the instance of circle within the CreateCircle class, so it never changes size.
Don't use static for what should be an instance variable, instead make use of the instance of the class you created and provide a setter method to change the variable...
Basically, this example passes the instance of p1 to the ControlPanel pane so that it has some context by which to manipulate what you have previously created.
import datetest.CircleShort.ControlPanel;
import datetest.CircleShort.CreateCircle;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Scrollbar;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollBar;
public class CircleShort extends JFrame {
CreateCircle p1 = new CreateCircle();
public CircleShort() {
CreateCircle p1 = new CreateCircle();
JFrame main = new JFrame();
main.setSize(new Dimension(600, 600));
main.setLocationRelativeTo(null);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setVisible(true);
Container c = main.getContentPane();
main.add(p1);
JFrame control = new JFrame();
control.setTitle("Control Panel");
control.setSize(new Dimension(300, 300));
control.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
control.setLocationRelativeTo(main);
control.setVisible(true);
ControlPanel p2 = new ControlPanel(p1);
control.add(p2);
}
static class CreateCircle extends JComponent {
int circleX = 100;
Ellipse2D.Double circle;
public CreateCircle() {
circle = new Ellipse2D.Double(circleX, 50, 400, 350);
}
public void setCircleX(int x) {
circleX = x;
circle = new Ellipse2D.Double(circleX, 50, 400, 350);
repaint();
}
public int getCircleX() {
return circleX;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red);
g2.fill(circle);
}
}
class ControlPanel extends JComponent {
private CreateCircle circle;
public ControlPanel(CreateCircle value) {
circle = value;
setLayout(new GridLayout(4, 0));
JButton change = new JButton("Click");
add(change);
JLabel info = new JLabel("Click Above To Change Color",
JLabel.CENTER);
add(info);
JLabel info1 = new JLabel("Slide Below To Change Size",
JLabel.CENTER);
add(info1);
JScrollBar slider = new JScrollBar(Scrollbar.HORIZONTAL, 0, 100, 0,
300);
add(slider);
slider.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
System.out.println(e.getValue());
circle.setCircleX((circle.getCircleX() + (e.getValue() % 5)));
}
});
}
}
static class CircleRun {
public static void main(String[] args) {
new CircleShort();
}
}
}
static is evil until you truly understand how to use it. If you find yourself making some field or method static just because you can't seem to figure out how to access it, then you are likely doing something wrong, be careful with it...
The next question this actually raises is, "why?"
A JSlider would be a more appropriate control to use and would be conceptually easier for a user to understand

Categories