I have such code, where I need to create some buttoms for customizing the square. It works, but after rolling up the frame the text field moves all over the frame and I don't know why. I mean when I execute the programm for first it's located in the right position that I mentioned using method setBounds(), but then it's located above the square. So how can I fix it?
import java.awt.*;
import java.awt.event.*;
import java.text.AttributedString;
import javax.swing.*;
import java.awt.font.TextAttribute;
public class Square extends JFrame implements ActionListener {
Button butt1 = new Button("Fill with yellow");
Button butt2 = new Button("Fill with red");
Button butt3 = new Button("Add label");
Button butt4 = new Button("");
Pan contentPane = new Pan();
public Square() {
super("Square");
this.setBounds(200, 100, 670, 400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().add(contentPane);
contentPane.setBounds(0, 0, 670, 275);
contentPane.setBackground(Color.BLACK);
add(butt1);
butt1.setBounds(25, 300, 190, 25);
butt1.addActionListener(this);
add(butt2);
butt2.setBounds(235, 300, 190, 25);
butt2.addActionListener(this);
butt3.setBounds(440, 300, 190, 25);
butt3.addActionListener(this);
add(butt3);
add(butt4);
}
#Override
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if (o == butt1) {
contentPane.draw(1);
}
else if (o == butt2) {
contentPane.draw(2);
}
else if (o == butt3) {
contentPane.draw(3);
}
}
public static void main(String[] args) {
Square w = new Square();
w.setVisible(true);
}
}
class Pan extends JPanel {
Graphics g;
Graphics2D g2;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(240, 70, 150, 150);
}
public void draw(int i) {
g = getGraphics();
super.paintComponent(g);
g2 = (Graphics2D) g.create();
switch(i) {
case 1: g2.setColor(Color.yellow);
g2.fillRect(240, 70, 150, 150);
break;
case 2: g2.setColor(Color.red);
g2.fillRect(240, 70, 150, 150);
break;
case 3:
g.setColor(Color.GRAY);
g.drawRect(240, 70, 150, 150);
JTextField text = new JTextField(25);
this.add(text);
Button add = new Button("Add");
add.setBounds(400, 230, 120, 25);
this.add(add);
text.setBounds(240, 230, 150, 25);
Font font = new Font("Veranda", Font.BOLD|Font.ITALIC, 24);
class AddButton extends JPanel implements ActionListener {
#Override
public void actionPerformed(ActionEvent ev) {
AttributedString label = new AttributedString(text.getText());
label.addAttribute(TextAttribute.FONT, font);
label.addAttribute(TextAttribute.FOREGROUND, Color.PINK);
g2.drawString(label.getIterator(), 240, 50);
}
}
AddButton listener = new AddButton();
add.addActionListener(listener);
break;
}
}
}
Okay lots of core issues and misunderstandings.
Swing uses layout managers. This is probably one of the first things you're butting heads again. Layout managers make decisions about how best to position components based on their individual algorithms.
Start by taking a look at Laying Out Components Within a Container for more details and make good use of them. GUIs are complex and dynamic things, with many factors going in to determining how components should be sized and positioned.
Painting. Another problem new developers have is understanding that they don't control the paint system. Swing uses a passive rendering system, which means it will paint when it feels its required.
You can provide hints when a new paint pass should be done by calling repaint, but it's up to the system to decide what and when something should be painted.
g = getGraphics(); is a bad idea on many levels. Apart from been able to return null, it's nothing more then a snapshot of the last paint pass and will be discarded when a new paint pass occurs.
Calling super.paintComponent(g); outside of a paint pass is also a bad idea. In fact, there should rarely ever be a need to call any of the paint methods directly.
This is NOT how custom painting should be done. Start by having a look at Performing Custom Painting and Painting in AWT and Swing for how painting works and how you should work with it
Also, mixing heavy weight (AWT) and light weight (Swing) components together is generally a bad idea should be avoid as much as possible.
Example...
So, I "hacked" you example into something a "little" more reasonable
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class Square extends JFrame implements ActionListener {
JButton butt1 = new JButton("Fill with yellow");
JButton butt2 = new JButton("Fill with red");
JButton butt3 = new JButton("Add label");
JButton butt4 = new JButton("");
Pan contentPane = new Pan();
public Square() {
super("Square");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().add(contentPane);
contentPane.setBackground(Color.BLACK);
JPanel actions = new JPanel();
actions.setBorder(new EmptyBorder(10, 10, 10, 10));
actions.add(butt1);
butt1.addActionListener(this);
actions.add(butt2);
butt2.addActionListener(this);
butt3.addActionListener(this);
actions.add(butt3);
// actions.add(butt4);
add(actions, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(null);
}
#Override
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if (o == butt1) {
contentPane.draw(1);
} else if (o == butt2) {
contentPane.draw(2);
} else if (o == butt3) {
contentPane.draw(3);
}
}
public static void main(String[] args) {
Square w = new Square();
w.setVisible(true);
}
}
class Pan extends JPanel {
private int state = -1;
private String text = null;
public Pan() {
Font font = new Font("Veranda", Font.BOLD | Font.ITALIC, 24);
setFont(font);
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(10, 10, 10, 10));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(670, 275);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(Color.GRAY);
g2.drawRect(240, 70, 150, 150);
switch (state) {
case 1:
g2.setColor(Color.yellow);
g2.fillRect(240, 70, 150, 150);
break;
case 2:
g2.setColor(Color.red);
g2.fillRect(240, 70, 150, 150);
break;
case 3:
g.setColor(Color.GRAY);
g.drawRect(240, 70, 150, 150);
break;
}
if (text != null) {
AttributedString label = new AttributedString(text);
label.addAttribute(TextAttribute.FONT, getFont());
label.addAttribute(TextAttribute.FOREGROUND, Color.PINK);
g2.drawString(label.getIterator(), 240, 50);
}
}
public void draw(int i) {
switch (i) {
case 3:
JTextField textField = new JTextField(25);
JButton add = new JButton("Add");
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.SOUTH;
this.add(textField, gbc);
gbc.gridx++;
this.add(add, gbc);
add.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ev) {
text = textField.getText();
remove(textField);
remove(add);
revalidate();
repaint();
}
});
revalidate();
repaint();
break;
}
state = i;
repaint();
}
}
Your code is full of, what is commonly known as, "magic numbers". These are values whose meaning is unknown.
Run the code and try resizing the window and you will see what I mean. Instead, you should be relying on "known" values, like getWidth and getHeight to make better determinations about how you should render the output
Related
import javax.swing.JFrame;
public class TrafficLight{
public static void main(String[]args){
JFrame frame = new JFrame("Traffic Light");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TrafficLightP panel = new TrafficLightP();
frame.getContentPane().add(new TrafficLightP());
frame.pack();
frame.setVisible(true);
}
}
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TrafficLightP extends JPanel {
private int count;
private JButton button;
private JLabel label;
public TrafficLightP(){
/*
Traffic light color coded as
1. Red
2. Yellow
3. Green
*/
button = new JButton ("Button!");
button.addActionListener(new ButtonListener());
label = new JLabel("Traffic Light Button");
add(button);
add(label);
setPreferredSize(new Dimension(400,300));
setBackground(Color.gray);
}
private class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent Event){
//Possible area where it messed up..?
count++;
count = count%3;
}
}
public void paintComponent (Graphics g){
TrafficLightP.super.paintComponent (g);
if (count == 0){
g.setColor(Color.red);
g.fillOval (20, 30, 50, 50);
}
else if (count == 1){
g.setColor(Color.yellow);
g.fillOval (20, 30, 50, 50);
}
else if (count == 2){
g.setColor(Color.green);
g.fillOval (20, 30, 50, 50);
}
g.setColor(Color.white);
}
}
Prompt: Design and implement an application that draws a traffic light and uses a push button to change the state of the light. Derive the drawing surface from the JPanel class and use another panel to organize the drawing surface and the button.
What have I done wrong in this case where the button doesn't change the color from red --> yellow --> green? If so, can someone give me advice for the future to fix problems like these? I haven't worked with JPanel much...
Alright, I figured out everything that I got but now I am really stuck. Every time you choose a different shape the previously selected one disappears. How do I make it so they don't disappear and stay on the screen until you exit?
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class ShapeStamper extends JFrame{
Random rand = new Random();
public int x;
public int y;
private JPanel panel1, panel2;
private JButton button1, button2, button3, button4;
private int option = 0;
public ShapeStamper(){
super("Shape Stamper!");
panel1 = new JPanel();
button1 = new JButton("Circle");
button2 = new JButton("Square");
button3 = new JButton("Rectangle");
button4 = new JButton("Oval");
button1.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent ae){
option = 1;
}
}
);
button2.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent ae){
option = 2;
}
}
);
button3.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent ae){
option = 3;
}
}
);
button4.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent ae){
option = 4;
}
}
);
panel2 = new JPanel();
panel2.setBackground(Color.WHITE);
MouseHandler mouse = new MouseHandler();
setVisible(true);
addMouseListener(mouse);
addMouseMotionListener(mouse);
add(panel2);
panel1.add(button1);
panel1.add(button2);
panel1.add(button3);
panel1.add(button4);
add(panel1, BorderLayout.SOUTH);
setSize(500,500);
setVisible(true);
}
private class MouseHandler extends MouseAdapter implements MouseMotionListener{
#Override
public void mousePressed(MouseEvent e){
x = e.getX();
y = e.getY();
repaint();
}
}
public void paint(Graphics g){
super.paintComponents(g);
Graphics2D g2d = (Graphics2D) g;
if(option == 0){
g.setFont(new Font("Serif", Font.BOLD, 32));
g.drawString("Shape Stamper!", 150, 220);
g.setFont(new Font("Serif", Font.ITALIC, 16));
g.drawString("Programmed by: Chris", 150, 230);
}
if(option == 1){
Color randColor1 = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
g2d.setPaint(randColor1);
g2d.drawOval(50, 50, 100, 100);
}
if(option == 2){
Color randColor2 = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
g2d.setPaint(randColor2);
g2d.drawRect(50, 50, 100, 100);
}
if(option == 3){
Color randColor3 = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
g2d.setPaint(randColor3);
g2d.draw(new Rectangle2D.Double(75,50,150,100));
}
if(option == 4){
Color randColor4 = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
g2d.setPaint(randColor4);
g2d.draw(new Ellipse2D.Double(50, 25, 100, 50));
}
}
public static void main(String[] args) {
ShapeStamper application = new ShapeStamper();
application.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
You should not be overriding paint of a top level container and then trying to painting over the top of the components you have already added.
The basic problem you will encounter is, the paint system is clever enough that it may not ever call paint of the frame, but simply update the child components directly instead.
Instead, create yourself a custom component, extending from something like JPanel and override it's paintComponent method and perform your custom painting there. Then add this component to your frame.
You will also find the the paint updates are cleaner and won't flicker when updated.
You should also make sure you are calling repaint on this custom component when ever you change one it's options to ensure that changes are painted back to the component
Take a look at Performing Custom Painting for more details.
Also, just to be clear, you should not be calling super.paintComponents from paint (or in fact anywhere except for when you override paintComponents...which there really should be a need to do...)
I am trying to create a simple GUI for a BST tree allowing insertions and deletions. However, I am having a lot of trouble inserting components onto the GUI during runtime.
What I thought of doing was to "refresh" the GUI every time an insertion or deletion happened. I created a method called printBst that creates Jlabels to display the numbered indexes as shown below, but they are not showing up.
I've tried to revalidate and validate the GUI afterwards but it still doesn't work. Anyone have any ideas?
package source;
import javax.swing.*;
import source.BST.BSTnode;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
public class Frame2 extends JFrame implements ActionListener{
BST bst;
JPanel displayPanel, buttonPanel, totalGUI;
JButton insertButton, deleteButton, resetButton;
JTextField insertField, deleteField;
public JPanel createContentPane (){
bst = new BST();
totalGUI = new JPanel();
totalGUI.setLayout(null);
displayPanel = new JPanel();
displayPanel.setLayout(null);
displayPanel.setLocation(10, 80);
displayPanel.setSize(400, 300);
totalGUI.add(displayPanel);
buttonPanel = new JPanel();
buttonPanel.setLayout(null);
buttonPanel.setLocation(10, 0);
buttonPanel.setSize(800, 80);
totalGUI.add(buttonPanel);
insertField = new JTextField(1);
insertField.addActionListener(this);
insertField.setLocation(0, 10);
insertField.setSize(150, 30);
buttonPanel.add(insertField);
insertButton = new JButton("Insert");
insertButton.setLocation(160, 10);
insertButton.setSize(150, 30);
insertButton.addActionListener(this);
buttonPanel.add(insertButton);
deleteField = new JTextField(1);
deleteField.addActionListener(this);
deleteField.setLocation(320, 10);
deleteField.setSize(150, 30);
buttonPanel.add(deleteField);
deleteButton = new JButton("Delete");
deleteButton.setLocation(480, 10);
deleteButton.setSize(150, 30);
deleteButton.addActionListener(this);
buttonPanel.add(deleteButton);
resetButton = new JButton("Reset");
resetButton.setLocation(640, 10);
resetButton.setSize(150, 30);
resetButton.addActionListener(this);
buttonPanel.add(resetButton);
totalGUI.setOpaque(true);
return totalGUI;
}
public void printBst(BSTnode node, int x, int x2, int y) {
if (node != null) {
JLabel current = new JLabel(""+ node.data);
current.setLocation((x+x2)/2, y);
current.setSize(100, 30);
current.setHorizontalAlignment(0);
displayPanel.add(current);
printBst(node.left, x, (x2+x)/2, y+60);
printBst(node.right, (x2+x)/2, x2, y+60);
System.out.println("here");
}
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == insertButton)
{
bst.insert(Integer.valueOf(insertField.getText()));
displayPanel.removeAll();
printBst(bst.root, 0, 800, 0);
totalGUI.revalidate();
validate();
}
else if(e.getSource() == deleteButton)
{
bst.delete(Integer.valueOf(deleteField.getText()));
displayPanel.removeAll();
printBst(bst.root, 0, 800, 0);
totalGUI.revalidate();
validate();
}
else if(e.getSource() == resetButton)
{
bst.clear();
displayPanel.removeAll();
printBst(bst.root, 0, 800, 0);
totalGUI.revalidate();
validate();
}
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("[=] JButton Scores! [=]");
Frame2 demo = new Frame2();
frame.setContentPane(demo.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(900, 400);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Make sure you call revalidate() and repaint() after you remove components from displayPanel ie:
displayPanel.removeAll();
printBst(0, 800, 0);
displayPanel.revalidate();
displayPanel.repaint();
Also, note that:
printBst(0, 800, 0);
results in invalid (not in bounds) coordinates inside displayPanel, which size is defined as (400, 300) The top-left corner of a window is 0,0. Try the following and you should see your label somewhere in the middle of the panel:
printBst(0, 400, 0);
Absolute positioning can be very difficult to manage. Check out A Visual Guide to Layout Managers and see if you can find an appropriate layout to help you.
You may also consider ready to go frameworks that can give you 2D canvas to work on. For example JGraph, JFreeChart or Piccolo2D.
I want to draw a line in a JPanel.
This is my GUI and I want a line in the JPanel in white.
I find many examples but the problem is the how to use it.
In many exmples, always they draw in a JFrame that extends from a JPanel.
I want to add the Panel to the Frame and add some buttons to draw lines in many directions and use the X button in center to clean the JPanel.
This is the code of the interface:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import javax.swing.JScrollPane;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class circuit extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
circuit frame = new circuit();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public circuit() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 559, 332);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 21, 359, 255);
contentPane.add(scrollPane);
JPanel panel = new JPanel();
scrollPane.setViewportView(panel);
panel.setBackground(Color.WHITE);
JLabel label = new JLabel("New label");
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
/////////////
}
});
label.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\up.png"));
label.setBounds(447, 66, 46, 48);
contentPane.add(label);
JLabel label_1 = new JLabel("New label");
label_1.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\down.png"));
label_1.setBounds(447, 159, 46, 48);
contentPane.add(label_1);
JLabel label_2 = new JLabel("New label");
label_2.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\right.png"));
label_2.setBounds(495, 112, 46, 48);
contentPane.add(label_2);
JLabel label_3 = new JLabel("New label");
label_3.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\left.png"));
label_3.setBounds(398, 112, 46, 48);
contentPane.add(label_3);
JLabel label_4 = new JLabel("New label");
label_4.setIcon(new ImageIcon("C:\\Users\\achermen\\Desktop\\1303860240_list-remove.png"));
label_4.setBounds(447, 112, 46, 48);
contentPane.add(label_4);
}
}
This is the code to draw a line
public void paint(Graphics graphics)
{
graphics.drawLine(10, 20, 300, 310);
}
So how to use this lines ....
Thanks in advance.
Best regards,
Ali
It may be easier to draw lines using the following approach:
click to mark the first endpoint
drag to show the line in progress
release to mark the second endpoint
This related example may offer some additional guidance.
Addendum
The example below implements the outline above.
I've update the example to show how to use a panel of buttons to affect the drawing.
See also this related example that uses the Action interface with key bindings.
I've updated this example to use Key Bindings.
LinePanel.java
import java.awt.BasicStroke;
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.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
/**
* #see https://stackoverflow.com/questions/6991648
* #see https://stackoverflow.com/questions/6887296
* #see https://stackoverflow.com/questions/5797965
*/
public class LinePanel extends JPanel {
private MouseHandler mouseHandler = new MouseHandler();
private Point p1 = new Point(100, 100);
private Point p2 = new Point(540, 380);
private boolean drawing;
public LinePanel() {
this.setPreferredSize(new Dimension(640, 480));
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.blue);
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(8,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
private class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
drawing = true;
p1 = e.getPoint();
p2 = p1;
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
drawing = false;
p2 = e.getPoint();
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
if (drawing) {
p2 = e.getPoint();
repaint();
}
}
}
private class ControlPanel extends JPanel {
private static final int DELTA = 10;
public ControlPanel() {
this.add(new MoveButton("\u2190", KeyEvent.VK_LEFT, -DELTA, 0));
this.add(new MoveButton("\u2191", KeyEvent.VK_UP, 0, -DELTA));
this.add(new MoveButton("\u2192", KeyEvent.VK_RIGHT, DELTA, 0));
this.add(new MoveButton("\u2193", KeyEvent.VK_DOWN, 0, DELTA));
}
private class MoveButton extends JButton {
KeyStroke k;
int dx, dy;
public MoveButton(String name, int code,
final int dx, final int dy) {
super(name);
this.k = KeyStroke.getKeyStroke(code, 0);
this.dx = dx;
this.dy = dy;
this.setAction(new AbstractAction(this.getText()) {
#Override
public void actionPerformed(ActionEvent e) {
LinePanel.this.p1.translate(dx, dy);
LinePanel.this.p2.translate(dx, dy);
LinePanel.this.repaint();
}
});
ControlPanel.this.getInputMap(WHEN_IN_FOCUSED_WINDOW)
.put(k, k.toString());
ControlPanel.this.getActionMap()
.put(k.toString(), new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
MoveButton.this.doClick();
}
});
}
}
}
private void display() {
JFrame f = new JFrame("LinePanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.add(new ControlPanel(), BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new LinePanel().display();
}
});
}
}
Is this going to work like an etch-a-sketch? Then you need to track the current position of the point.
Point current = new Point(0, 0); //for example.
Then when the user clicks the buttons you can simply increment or decrement x and y accordingly.
On left arrow:
current.setX(current.getX() - INC);
where INC could be a variable that specifies the length of the distance to draw the line. Maybe 5? Always set a second point p1 to the previous location though.
It is always easier to create a class that extends Canvas or JPanel to draw on rather than draweing directly on the JFrame.
e.g.
public class Circuit extends JFrame {
Point p1, current;
JPanel drawPanel;
//your other declarations
public Circuit(){
super();
drawPanel = new DrawPanel();
p1 = new Point(0, 0);
current = new Point(0, 0);
add(drawPanel, BorderLayout.CENTER);
//your other code
}
class DrawingPanel extends JPanel{
public void paintComponent(Graphics g){
g.drawLine(p1.getX(), p1.getY(), current.getX(), current.getY());
}
}
//the rest of your code.
}
There is a simple answer for triggering graphics: e.g. The following code can be placed inside a click event and used for drawing a few simple objects on a jPanel. jPanel1 in this case was situated on one side of a tabbed jPanel7 and next to the triggering button. To do this in netbeans GUI, the code was placed inside the button action event. Once the usual errors appeared for not having the proper imports, right click on the code and click on "fix imports". Bingo, all is well :-) Warning: the setBackground command for the panel will override the graphics object. If you set the background color without using the graphics object, you will not see your objects!
Graphics g = jPanel1.getGraphics();
g.setColor(Color.blue);
g.drawLine( 0, 50, 20, 50);
g.setColor(Color.white);
g.fillRect(40, 50, 20, 20);
g.setColor(Color.blue);
g.drawRect(40, 50, 20, 20);
g.drawOval(80, 50, 20, 20);
g.setColor(Color.green);
g.fillOval(80, 50, 18, 18);
This restores your faith in true love :-)
The difficulty here is that any change or repaint will erase your effort. This approach is specifically discouraged by the Java founders. But in the current rendition of Netbeans Swing, where extending the jPanel is made difficult by locking code changes, this approach could be your only short term solution. A simple persistent graphic extension for the jPanel would be a most welcome addition to the current Netbeans Swing environment, a graphics panel. This would allow you to drag and drop the graphics panel and then get on with the event driven use of that panel. 40 other IDE's already have this, it seems Java has been slow to add this feature.
Someone told me a way to paint onto a Jframe and it worked fine in the example, but now I have tabs it doesn't paint onto them.
I need the paint/drawLine to work in my Tabbed example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.io.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
public class GUI extends JTabbedPane implements ActionListener
{
static JFrame aWindow = new JFrame("Project");
JTabbedPane myTabs = new JTabbedPane();
JPanel loginMainPanel = new JPanel();
JPanel displayMainPanel = new JPanel();
JPanel editMainPanel = new JPanel();
JTextField myText1 = new JTextField("");
JTextField myText2 = new JTextField("");
JTextField myText3 = new JTextField("");
JLabel loginLabel = new JLabel("Username:");
JTextField loginField = new JTextField();
JLabel loginLabel2 = new JLabel("Password:");
JPasswordField loginPass = new JPasswordField();
JButton displayButton = new JButton("Load Data");
JButton loginButton = new JButton("Login");
JLabel editLabel = new JLabel("Write:");
JTextArea editArea = new JTextArea();
public GUI()
{
Toolkit theKit = aWindow.getToolkit();
Dimension wndSize = theKit.getScreenSize();
aWindow.setBounds(wndSize.width/3, wndSize.height/3, 250, 250);
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout grid = new GridLayout(1,1);
Container content = aWindow.getContentPane();
content.setLayout(grid);
createLoginPanel();
createDisplayPanel();
createEditPanel();
myTabs.addTab("Login", loginMainPanel);
myTabs.addTab("Main Menu", displayMainPanel);
myTabs.addTab("Setting", editMainPanel);
myTabs.setSelectedIndex(0);
myTabs.setEnabledAt(1,false);
myTabs.setEnabledAt(2,false);
content.add(myTabs);
aWindow.setVisible(true);
}
public void createLoginPanel()
{
loginMainPanel.setLayout(null);
loginLabel.setBounds(10, 15, 150, 20);
loginMainPanel.add(loginLabel);
loginField.setBounds(10, 35, 150, 20);
loginMainPanel.add(loginField);
loginLabel2.setBounds(10, 60, 150, 20);
loginMainPanel.add(loginLabel2);
loginPass.setBounds(10, 80, 150, 20);
loginMainPanel.add(loginPass);
loginButton.addActionListener(this);
loginButton.setBounds(50, 110, 80, 20);
loginMainPanel.add(loginButton);
}
public void createDisplayPanel()
{
displayMainPanel.setLayout(null);
displayButton.addActionListener(this);
displayButton.setBounds(50, 80, 150, 20);
displayMainPanel.add(displayButton);
myText1.setBounds(50, 170, 200, 30);
myText2.setBounds(50, 140, 200, 30);
myText3.setBounds(50, 110, 200, 30);
displayMainPanel.add(myText1);
displayMainPanel.add(myText2);
displayMainPanel.add(myText3);
}
public void createEditPanel()
{
editMainPanel.setLayout(null);
editLabel.setBounds(10, 15, 150, 20);
editMainPanel.add(editLabel);
editArea.setBounds(10, 65, 150, 50);
editMainPanel.add(editArea);
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == loginButton)
{
//myTabs.setSelectedIndex(1);
}
}
public void paint(Graphics g) {
super.paint(g);
int locX = 0;
int locY = 0;
int destX = 210;
int destY = 210;
g.setColor(Color.red);
// draw a line (there is now drawPoint..)
g.drawLine(locX, locY, destX, destY);
}
public static void main(String[] args)
{
GUI tw1 = new GUI();
}
}
How can I find a solution so it will paint that line on the tab (loginMainPanel)?
If you want custom drawing on a JPanel, you should create a custom class that extends JPanel:
class CustomPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(x1, y1, x2, y2);
}
}
Then:
JPanel loginMainPanel = new JPanel();
Woudl become:
JPanel loginMainPanel = new CustomPanel();
Sorry for the blurge of bloated code
Yes, well that is why people can't solve problems, because the code is so bloated you can't see what you are doing.
If you want us to help you problem solve then you need to post a SSCCE
Someone told me a way to paint onto a Jframe
Well, that is wrong, in general you should not be overrding the paint() method, unless you have a specific reason.
Also, your whole program is wrong because you are extending JTabbedPane. You should never do this to create a GUI.
Your paint() method is never invoked because you never use that class anywhere. Look at your code. For your class variables you create a new JTabbedPane. Then in the constructor you add all these components to the frame and make the frame visible.
You need to take a look at the Swing tutorial and follow some of the example there for a better way to create a simple GUI.
I don't understand what you are trying to do by drawing a line on the tabbed pane. A tabbed pane displays different panels every time you click on a tab. Where exactly do you want the line to appear?
Also, you should learn how to use layout managers. Using a null layout will cause unnecessary problems.
Until you post a SSCCE, I can't be of much help.