how to draw below a label / button? -JAVA
I wanted to write a coordinate calculation program for ax^2 + bx + c, but thats not the important point...
I'd like to draw the graph only via AWT and the paint method. (not implemented yet), but I'm not able to set the paint method in the foreground. Can you please help me to fix the problem so that the paint is at least visible?
I have attached a outline of my thoughts.
Sorry for my bad english
idea
import java.awt.Button;
import java.awt.Canvas;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
public class MyWindow extends Frame {
Frame frame;
Label l1;
Label l2;
Label l3;
Button b1;
TextField t1;
TextField t2;
TextField t3;
Panel panel;
Canvas canvas;
MyWindow() {
frame = new Frame("GraphPlotter");
frame.setSize(800, 800);
frame.setLayout(new FlowLayout());
l1 = new Label("f(x)= ");
l2 = new Label(" x^2 + ");
l3 = new Label(" x + ");
t1 = new TextField("1");
t2 = new TextField("2");
t3 = new TextField("3");
b1 = new Button("Plot");
frame.add(l1);
frame.add(t1);
frame.add(l2);
frame.add(t2);
frame.add(l3);
frame.add(t3);
frame.add(b1);
frame.setVisible(true);
}
public void paint(Graphics g) {
g.fillRect(10, 10, 300, 300); // ist im "Hintergrund"??
}
}
` public class Start {
public static void main(String[] args) {
MyWindow window = new MyWindow();
}
}
`
You haven't set a color before
g.fillRect(10, 10, 300, 300);
I solved that problem like two months or so, but I'm a bit motivated at the moment, so I am going to answer my question on my own. Info: repaint() calls paint, so you don't have to implement this method on your own.
in the task I forgot to:
-generate a canvas
-use layout manager
-call paint with the methods repaint(); or update();
The question was only how to paint and this should be clear after reading following code:
package delete;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextField;
public class AwtFrame extends Frame {
AwtCanvas c;
Panel p1;
Label la_ax2, la_bx, la_c;
TextField tf_Ax2, tf_bx, tf_c;
public AwtFrame() {
super("paint example.");
this.setSize(800, 800);
initComp();
addComp();
// TODO: write a graph drawing method
c.repaint(); // paints a line of your graph
this.setVisible(true);
}
public void initComp() {
p1 = new Panel();
la_ax2 = new Label("x^2 ");
la_bx = new Label("+ x ");
la_c = new Label("+ c ");
tf_Ax2 = new TextField(0);
tf_bx = new TextField(0);
tf_c = new TextField(0);
c = new AwtCanvas();
}
public void addComp() {
this.setLayout(new BorderLayout());
p1.setLayout(new FlowLayout());
this.add(p1, BorderLayout.NORTH);
this.add(c, BorderLayout.CENTER);
p1.add(tf_Ax2);
p1.add(la_ax2);
p1.add(tf_bx);
p1.add(la_bx);
p1.add(tf_c);
p1.add(la_c);
}
public static void main(String[] args) {
new AwtFrame();
}
}
package delete;
import java.awt.Canvas;
import java.awt.Graphics;
import java.util.LinkedList;
public class AwtCanvas extends Canvas {
// LinkedList<ToImplement> coords = new LinkedList<ToImplement>();
// TODO: implement plotter
public void paint(Graphics g) {
g.drawLine(40, 40, 100, 100);
g.drawLine(54, 22, 300, 200);
}
}
Related
I was working on an overlay for a JPanel but I have a slight problem, the transparency of the overlay sees straight through to the JFrame.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class GUI extends JFrame {
private GUI() {
super("Recorder Part");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JLayeredPane layers = new Overlay();
add(layers);
pack();
getContentPane().setBackground(Color.GREEN);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new GUI());
}
private class Overlay extends JLayeredPane {
JPanel base;
JPanel overlay;
private Overlay() {
setPreferredSize(new Dimension(800, 100));
createBase();
createOverlay();
add(base, new Integer(0));
add(overlay, new Integer(1));
}
private void createBase() {
base = new JPanel();
base.setPreferredSize(new Dimension(800, 100));
base.setBounds(0, 0, 800, 100);
base.setBackground(Color.BLUE);
base.setOpaque(true);
base.add(new JLabel("Hello"));
}
private void createOverlay() {
overlay = new JPanel();
overlay.setPreferredSize(new Dimension(800, 100));
overlay.setBounds(0, 0, 800, 100);
overlay.setBackground(new Color(255, 0, 0, 0));
}
}
}
How can I fix this so that when the JPanel called overlay is transparent, the Jpanel called base can be seen and not the JFrame?
Edit
I found that this problem only occurs when the overlay panel has one dimension that is greater than or equal to the dimensions of the base panel. This can be seen by adjusting the size of the frame in this example.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class GUI extends JFrame {
private GUI() {
super("Recorder Part");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JLayeredPane layers = new Overlay();
add(layers);
pack();
getContentPane().setBackground(Color.GREEN);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new GUI());
}
private class Overlay extends JLayeredPane {
JPanel base;
JPanel overlay;
private Overlay() {
addComponentListener(new Resize());
setPreferredSize(new Dimension(800, 100));
createBase();
createOverlay();
add(base, new Integer(0));
add(overlay, new Integer(1));
}
private void createBase() {
base = new JPanel();
base.setLocation(0, 0);
base.setBackground(Color.BLUE);
base.setOpaque(true);
base.add(new JLabel("Hello"));
}
private void createOverlay() {
overlay = new JPanel();
overlay.setLocation(0, 0);
overlay.setSize(new Dimension(800, 100));
overlay.setBackground(new Color(255, 0, 0, 128));
}
private class Resize extends ComponentAdapter {
#Override
public void componentResized(ComponentEvent e) {
System.out.println("Resized");
base.setSize(new Dimension(getParent().getWidth(), getParent().getHeight()));
}
}
}
}
This is undesirable as the overlay panel needs to be the exact same size of the base panel. I would appreciate any help.
I have the felling that this is a bug. Change the bounds so it doesn't fully overlap the base to o see what happens:
overlay.setBounds(0, 0, 799, 100); // or (1, 0, 800, 100)
probably some kind of optimization, like ignoring a component if it is being completely obscured by another component, but without considering transparency in that optimization [:-|
EDIT:
that is definitively the problem - paintChildren of JComponent does some kind of optimization based on children being totally obscured by other children.
I found two solutions, the first one is probably the correct one- set the overlay to non-opaque:
overlay.setOpaque(false);
this has the drawback that the background color is not being used at all.
Second is more a workarround - make the JLayeredPane return true for optimizedDrawingEnabled, this will stop the JComponent from doing it:
private class Overlay extends JLayeredPane {
/// ...
#Override
public boolean isOptimizedDrawingEnabled() {
return true;
}
}
but not sure what may stop working by doing that, so I would prefer the first solution!
Coding is here.
I can't create any rectangle or circle inside frame.
the object of this project is to create converting celcius 2 Farenheit & Farenheit 2 Celcius.
so what I want is, please teach me to how to draw rectangle or oval in side the frame.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class C2F extends JComponent{
private double input1, output1;
private double input2, output2;
JPanel center = new JPanel();
JPanel top = new JPanel();
JPanel east = new JPanel();
JPanel south = new JPanel();
//for giving input & output
C2F(){
JFrame frame = new JFrame();
frame.setTitle("C2F");
frame.setSize(700,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.getContentPane().add(top,BorderLayout.NORTH);
frame.getContentPane().add(center,BorderLayout.CENTER);
frame.getContentPane().add(south,BorderLayout.SOUTH);
frame.getContentPane().add(east,BorderLayout.EAST);
frame.setVisible(true);
CC2F();
}
public void CC2F(){
//making frame
//give specific location
JLabel L1 = new JLabel("Please input Celcius or Fahrenheit to Convert");
top.add(L1);
JLabel l1 = new JLabel("Cel -> Fah");
south.add(l1);
JTextField T1 = new JTextField(12);
south.add(T1);
JButton B1 = new JButton("Convert");
south.add(B1);
JLabel l2 = new JLabel("Fah -> Cel");
south.add(l2);
JTextField T2 = new JTextField(12);
south.add(T2);
JButton B2 = new JButton("Convert");
south.add(B2);
//to create buttons and labels to give an answer
B1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
input1 = Double.parseDouble(T1.getText());
output1 = input1 *(9/5) + 32;
T2.setText(""+output1);
repaint();
}
});
B2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
input2 = Double.parseDouble(T2.getText());
output2 = (input2 - 32)/9*5;
T1.setText(""+output2);
}
});
//making events
//placing the buttons and labels
output1 = 0;
output2 = 0;
//initialize the value
}
public void paintComponent(Graphics g) {
//error spots. it compiles well. But this is not what I want.
super.paintComponent(g);
Graphics2D gg = (Graphics2D) g;
gg.setColor(Color.BLACK);
gg.drawOval(350, 500,12,12);
gg.setColor(Color.RED);
gg.fillRect(350, 500, 10,(int) output1);
gg.fillOval(350, 500, 10, 10);
gg.setColor(Color.RED);
gg.fillRect(350, 500, 10,(int) output2);
gg.fillOval(350, 500, 10, 10);
//to draw stuffs
}
public static void main(String[] args)
{//to run the program
new C2F();
}
}
You never actually add C2F to anything that would be able to paint it, therefore your paint method will never be called.
You should override paintComponent instead of paint, as you've broken the paint chain for the component which could cause no end of issues with wonderful and interesting paint glitches. Convention would also suggest that you should call super.paintComponent (when overriding paintComponent) as well before you perform any custom painting
See Painting in AWT and Swing and Performing Custom Painting for more details
As a general piece of advice, I'd discourage you from creating a frame within the constructor of another component, this will make the component pretty much unusable again (if you wanted to re-use it on another container for example)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class C2F extends JComponent {
public C2F() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
TestPane center = new TestPane();
JPanel top = new JPanel();
JPanel east = new JPanel();
JPanel south = new JPanel();
//give specific location
JLabel L1 = new JLabel("Please input Celcius or Fahrenheit to Convert");
top.add(L1);
JLabel l1 = new JLabel("Cel -> Fah");
south.add(l1);
JTextField T1 = new JTextField(12);
south.add(T1);
JButton B1 = new JButton("Convert");
south.add(B1);
JLabel l2 = new JLabel("Fah -> Cel");
south.add(l2);
JTextField T2 = new JTextField(12);
south.add(T2);
JButton B2 = new JButton("Convert");
south.add(B2);
//to create buttons and labels to give an answer
B1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
double input1 = Double.parseDouble(T1.getText());
double output1 = input1 * (9 / 5) + 32;
T2.setText("" + output1);
center.setOutput1(output1);
}
});
B2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
double input2 = Double.parseDouble(T2.getText());
double output2 = (input2 - 32) / 9 * 5;
T1.setText("" + output2);
center.setOutput2(output2);
}
});
//making events
frame.getContentPane().add(top, BorderLayout.NORTH);
frame.getContentPane().add(center, BorderLayout.CENTER);
frame.getContentPane().add(south, BorderLayout.SOUTH);
frame.getContentPane().add(east, BorderLayout.EAST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private double output1, output2;
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 600);
}
public void setOutput1(double output1) {
this.output1 = output1;
repaint();
}
public void setOutput2(double output2) {
this.output2 = output2;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.drawOval(350, 500, 12, 12);
g2d.setColor(Color.RED);
g2d.fillRect(350, 0, 10, (int) output1);
g2d.fillOval(350, 0, 10, 10);
g2d.setColor(Color.BLUE);
g2d.fillRect(350, 0, 10, (int) output2);
g2d.fillOval(350, 0, 10, 10);
g2d.dispose();
}
}
public static void main(String[] args) {//to run the program
new C2F();
}
}
I am a high school student trying to teach myself GUI basics. The program I am trying to write would take two numbers from the user and then plot those two numbers in a graph. The user can also enter more points if he or she likes. The problem I am having is that when I press the button that opens the GUI that should be the graph, the GUI appears but it is blank. I think there is an issue with the paint method and the way that is being set up and called but I am not sure. Thanks in advance for any advice or help.
This is the class that creates the graph GUI:
package dataGraph;
import javax.swing.*;
import java.awt.*;
import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Graphics2D;
public class graphGUI extends JFrame {
//public Graphics2D g2;
public graphGUI() {
setTitle("Data Graph");
setSize(500, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
}
public void paint(Graphics g) {
super.paintComponents(g);
g.drawLine(40, 425, 450, 425);
g.drawLine(40, 425, 40, 70);
g.drawString("Graph", 20, 20);
// g2.draw
g.drawLine(50, 50, 50, 50);
for(int i = 0; i < dataEntryGUI.x.size(); i++){
g.drawOval(Integer.parseInt(dataEntryGUI.x.get(i)),
Integer.parseInt(dataEntryGUI.y.get(i)),5,5);
}
}
}
This is the class that creates the GUI for data entry and has the action listener that allows the user to add more "points" and then "graph" them:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JFrame;
public class dataEntryGUI extends JFrame implements ActionListener {
public static ArrayList<String> x;
public static ArrayList<String> y;
private Button btnAdd;
private Button btnGraph;
private Label lbl;
private Label lbl2;
private TextField xInt;
private TextField yInt;
public dataEntryGUI() {
setTitle("Data entry");
setSize(250, 250);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
lbl = new Label("x");
lbl2 = new Label("y");
// text fields
xInt = new TextField();
yInt = new TextField();
x = new ArrayList<String>();
y = new ArrayList<String>();
// add button
btnAdd = new Button("Add another");
// btnAdd.setPreferredSize(new Dimension(70,30));
btnAdd.addActionListener(this);
btnGraph = new Button("Make Graph");
btnGraph.addActionListener(this);
add(lbl);
add(xInt);
add(lbl2);
add(yInt);
add(btnAdd);
add(btnGraph);
setLayout(new FlowLayout());
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
// System.out.println("boogers");
if (e.getSource() == btnAdd) {
//xInt.getText();
x.add(xInt.getText());
y.add(yInt.getText());
xInt.setText("");
yInt.setText("");
} else {
graphGUI graph = new graphGUI();
graph.repaint();
}
}
}
And this is the main method:
package dataGraph;
public class dataGraphMain {
public static void main(String[] args) {
dataEntryGUI gui = new dataEntryGUI();
//graphGUI gui2 = new graphGUI();
}
}
public void paint(Graphics g) {
super.paintComponents(g);
In general, whenever you override a method you should be invoking "super" on the method name you are overriding, not some other method. That is in this case you would invoke:
super.paint(g);
However, for custom painting you should NOT override the paint() method of a JFrame.
Instead you should override the paintComponent(...) method of a JPanel and then add the panel to the frame. Read the section from the Swing tutorial on Custom Painting for more information and examples.
I am a high school student trying to teach myself GUI basics.
Keep a link to the Table of Contents of the Swing tutorial handy for future reference as the tutorial covers the basics and more.
As mentioned by camickr, some refactoring should be done. Perhaps this will help.
First, you are trying to repaint the JFrame. This is not recommended. What you want to do is define a JPanel to work on and add it to the frame's pane content.
I refactored your code a bit, so that GraphGUI is now a JPanel, and not a JFrame. This way, you can use it as a component in any future JFrame you might create.
Second, I defined a function within DataEntryGUI that creates a new frame, which will hold the graph component and paint it. Here's the complete code:
Class GraphGUI
package dataGraph;
import javax.swing.*;
import java.awt.*;
import java.awt.Graphics;
public class graphGUI extends JPanel {
public GraphGUI() {
setBackground(Color.WHITE);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(40, 425, 450, 425);
g.drawLine(40, 425, 40, 70);
g.drawString("Graph", 20, 20);
g.drawLine(50, 50, 50, 50);
for(int i = 0; i < dataEntryGUI.x.size(); i++){
g.drawOval(Integer.parseInt(dataEntryGUI.x.get(i)),
Integer.parseInt(dataEntryGUI.y.get(i)),5,5);
}
}
}
DataEntryGUI
package dataGraph;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JFrame;
public class DataEntryGUI extends JFrame implements ActionListener {
public static ArrayList<String> x; //This should be figured out by
public static ArrayList<String> y; //the OP. Encapsulation and
//decoupling is a different matter.
private Button btnAdd;
private Button btnGraph;
private Label lbl;
private Label lbl2;
private TextField xInt;
private TextField yInt;
public DataEntryGUI() {
setTitle("Data entry");
setSize(250, 250);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
lbl = new Label("x");
lbl2 = new Label("y");
// text fields
xInt = new TextField();
yInt = new TextField();
x = new ArrayList<String>();
y = new ArrayList<String>();
// add button
btnAdd = new Button("Add another");
// btnAdd.setPreferredSize(new Dimension(70,30));
btnAdd.addActionListener(this);
btnGraph = new Button("Make Graph");
btnGraph.addActionListener(this);
add(lbl);
add(xInt);
add(lbl2);
add(yInt);
add(btnAdd);
add(btnGraph);
setLayout(new FlowLayout());
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
// System.out.println("boogers");
if (e.getSource() == btnAdd) {
//xInt.getText();
x.add(xInt.getText());
y.add(yInt.getText());
xInt.setText("");
yInt.setText("");
} else {
paintGraph();
}
}
private void paintGraph() {
JFrame graphFrame = new JFrame();
GraphGUI graph = new GraphGUI();
graphFrame.getContentPane().add(graph);
graphFrame.setTitle("Data Graph");
graphFrame.setSize(500, 500);
graphFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
graphFrame.setResizable(false);
graphFrame.setVisible(true);
}
}
This seems to exhibit the behavior you wanted. I have some thoughts/comments on how you pass your x,y data (and the fact that they are public and not private), but this is beyond the scope of what you needed here.
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
So I have this problem with my code. Whenever I load up the game there is a red square in the center of the screen, and I have not programmed it to do so. I have tried to find the error for hours but I just can't see it. I think it has to do with the panels or something. The second thing is that when I press the button to draw the grid, only a small line appears. It is programmed to be much bigger than what it is, and it is not in the right location either. Below is all my code, and any help is greatly appreciated!!
package com.theDevCorner;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
public class Game extends JPanel implements ActionListener {
public static JButton grid = new JButton("Show Grid");
public static JPanel drawArea = new JPanel();
public static JMenuBar menu = new JMenuBar();
public static JPanel notDrawn = new JPanel();
public static boolean gridPressed = false;
public Game() {
grid.addActionListener(this);
}
public static void main(String args[]) {
Game game = new Game();
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(new Dimension(
Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit
.getDefaultToolkit().getScreenSize().height));
frame.setTitle("Game");
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
menu.setSize(new Dimension(1600, 20));
menu.setLocation(0, 0);
notDrawn.setBackground(new Color(255, 0, 50));
notDrawn.setSize(100, 900);
notDrawn.add(grid);
notDrawn.setLayout(null);
grid.setSize(new Dimension(100, 25));
grid.setLocation(0, 25);
drawArea.setSize(new Dimension((Toolkit.getDefaultToolkit()
.getScreenSize().width), Toolkit.getDefaultToolkit()
.getScreenSize().height));
drawArea.setLocation(100, 0);
drawArea.setBackground(Color.black);
drawArea.add(menu);
drawArea.add(game);
frame.add(drawArea);
frame.add(notDrawn);
}
public void paint(Graphics g) {
Game game = new Game();
if (gridPressed) {
Game.drawGrid(0, 0, g);
}
g.dispose();
repaint();
}
public static void drawGrid(int x, int y, Graphics g) {
g.setColor(Color.white);
g.drawLine(x, y, 50, 300);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == grid && gridPressed == true) {
gridPressed = false;
System.out.println("Unpressed");
}
if (e.getSource() == grid) {
gridPressed = true;
System.out.println("Pressed");
}
}
}
There are a number of problems...
The red "square" you are seeing is actually your grid button. The reason it's red is because of your paint method.
Graphics is a shared resource, that is, each component that is painted on the screen shares the same Graphics context. Because you chose to dispose of the context and because you've failed to honor the paint chain, you've basically screwed it up.
Don't EVER dispose of a Graphics context you didn't create. It will prevent anything from being painted to it again. Always call super.paintXxx. The paint chain is complex and does a lot of very important work. If you're going to ignore it, be ready to have to re-implement it.
null layouts are vary rarely the right choice, especially when you're laying out components. You need to separate your components from your custom painting, otherwise the components will appear above the custom painting.
This frame.setSize(new Dimension(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height)) is not the way to maximize a window. This does not take into consideration the possibility of things like tasks bars. Instead use Frame#setExtendedState
As Andreas has already commented, you actionPerformed logic is wrong. You should be using an if-statement or simply flipping the boolean logic...
Updated with simple example
ps- static is not your friend here...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Game extends JPanel implements ActionListener {
private GridPane gridPane;
public Game() {
setLayout(new BorderLayout());
SideBarPane sideBar = new SideBarPane();
sideBar.addActionListener(this);
add(sideBar, BorderLayout.WEST);
gridPane = new GridPane();
add(gridPane);
}
public static void main(String args[]) {
Game game = new Game();
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setTitle("Game");
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(game);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equalsIgnoreCase("grid")) {
gridPane.setGridOn(!gridPane.isGridOn());
}
}
public class GridPane extends JPanel {
private boolean gridOn = false;
public GridPane() {
setBackground(Color.BLACK);
}
public boolean isGridOn() {
return gridOn;
}
public void setGridOn(boolean value) {
if (value != gridOn) {
this.gridOn = value;
repaint();
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (gridOn) {
g.setColor(Color.white);
g.drawLine(0, 0, 50, 300);
}
}
}
public class SideBarPane extends JPanel {
public JButton grid;
public SideBarPane() {
setBackground(new Color(255, 0, 50));
setLayout(new GridBagLayout());
grid = new JButton("Show Grid");
grid.setActionCommand("grid");
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTH;
gbc.weighty = 1;
add(grid, gbc);
}
public void addActionListener(ActionListener listener) {
grid.addActionListener(listener);
}
}
}