I have this code:
package test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test extends JFrame implements ActionListener {
private JPanel panel;
private JButton button;
private JTextField field,field2;
private JLabel labelx, labely;
public static void main(String[] args) {
Test Frame = new Test();
Frame.setSize(400, 400);
Frame.createGUI();
Frame.setVisible(true);
}
private void createGUI(){
setDefaultCloseOperation (EXIT_ON_CLOSE);
Container window = getContentPane();
window.setLayout(new FlowLayout());
panel = new JPanel();
panel.setPreferredSize(new Dimension(300, 300));
panel.setBackground(Color.white);
window.add(panel);
button = new JButton();
button.setText("Teken water molecuul");
button.setBackground(Color.yellow);
button.addActionListener(this);
window.add(button);
labelx = new JLabel("x");
field = new JTextField(2);
labely = new JLabel("y");
field2 = new JTextField(2);
window.add(labelx);
window.add(field);
window.add(labely);
window.add(field2);
}
#Override
public void actionPerformed(ActionEvent e) {
Graphics paper = panel.getGraphics();
String x = field.getText();
String y = field2.getText();
//panel.setLocation(x,y); //this x and y don't work
paper.setColor(Color.blue);
paper.fillOval(50,50,50,50);
paper.fillOval(50,200,50,50);
paper.setColor(Color.black);
paper.drawLine(92,92,150,150);
paper.drawLine(92,207,150,150);
paper.setColor(Color.red);
paper.fillOval(100,100,100,100);
}
}
I want to set the location of the graphic to a specific X and Y coordinates I got using two textFields. If I change the x and y manualy to a number, the white screen moves. I don't want to move the white screen but only the graphic.
So, the input of the two textFields should determine the position of the graphic.
Result when I run the code now. The position isn't determined by the input of the text textFields now.
Custom painting is done by override the paintComponent(...) method of your panel, not by using the getGraphics() method.
So you need to create a custom class. This class would have two instance variables to control the x/y location. Then the painting code would reference these variables. You would also need to add a setter method to change the value of these variables.
The basic code would be something like:
public class CustomPainting extends JPanel
{
private int locationX;
private int locationY;
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.translate(locationX, locationY)
// add your painting code here
}
public setGraphicLocation(int locationX, int locationY)
{
this.locationX = locationX;
this.locationY = locationY;
repaint;
}
}
Then in the ActionListener code you need to invoke the setGraphicLocation( ) method of your custom class using the value found in the text fields.
Read the section from the Swing tutorial on Custom Painting for more information and working examples.
Related
I have written this code however I am having trouble with one aspect I wish to code into it. I want to make the green square change size when I press one of the three buttons I have so when I press the button 'small' the square changes size to small e.g. 100 and when I press the button 'medium' it changes size to medium e.g. 400. This is my code so far:
package Lab2;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main {
public static void main(String[] args) {
FilledFrame frame = new FilledFrame();
frame.setVisible( true );
}
}
class FilledFrame extends JFrame {
int size = 400;
public FilledFrame()
{
JButton butSmall = new JButton("Small");
JButton butMedium = new JButton("Medium");
JButton butLarge = new JButton("Large");
JButton butMessage = new JButton("Say Hi");
SquarePanel panel = new SquarePanel(this);
JPanel butPanel = new JPanel();
butPanel.add(butSmall);
butPanel.add(butMedium);
butPanel.add(butLarge);
butPanel.add(butMessage);
add(butPanel, BorderLayout.NORTH);
add(panel, BorderLayout.CENTER);
setSize( size+100, size+100 ); } }
class SquarePanel extends JPanel {
FilledFrame theApp;
SquarePanel(FilledFrame app)
{
theApp = app;
}
public void paintComponent ( Graphics g)
{
super.paintComponent(g);
g.setColor(Color.green);
g.fillRect(20, 20, theApp.size, theApp.size);
}
}
class buttonHandler implements ActionListener {
FilledFrame theApp;
int size;
public buttonHandler(FilledFrame app, int size) {
theApp = app;
this.size = size;
}
#Override
public void actionPerformed (ActionEvent e){
theApp.setSize(this.size, this.size);
}
}
As I don't see any event listeners for your buttons, I assume this is all the code you have. Your buttons will not do anything unless you tell them to do it. You need to add event listeners, and through that change the size and update the panel.
Example:
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
theApp.size = 200;
frame.getContentPane().repaint();
//OR frame.repaint();
}
});
EDIT:
The problem with using the button handler class is you would need to find which buttton was pressed, instead its easier to use the way I showed above. I edited the code above, try copy pasting to one of the buttons.
Current code
ThreeColorButton class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ThreeColorButton {
private static CompositeIcon icons = new CompositeIcon();
private static JPanel panel = new JPanel();
private static JFrame frame = new JFrame();
private static JLabel label = new JLabel();
public static void main(String[] args) {
//create rgb buttons
JButton redButton = new JButton("Red");
JButton greenButton = new JButton("Green");
JButton blueButton = new JButton("Blue");
//add rgb buttons to panel
panel.add(redButton);
panel.add(greenButton);
panel.add(blueButton);
//add action listeners to buttons
redButton.addActionListener(buttonListener(40, Color.red));
greenButton.addActionListener(buttonListener(40, Color.green));
blueButton.addActionListener(buttonListener(40, Color.blue));
frame.setLayout(new BorderLayout());
frame.add(panel, BorderLayout.NORTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private static ActionListener buttonListener(final int size,final Color color) {
return new ActionListener() {
public void actionPerformed(ActionEvent event) {
SquareIcon icon = new SquareIcon(size, color);
icons.addIcon(icon);
label.setIcon(icons);
frame.add(label, BorderLayout.SOUTH);
frame.repaint();
frame.pack();
}
};
}
}
CompositeIcon code
import javax.swing.*;
import java.awt.*;
import java.util.*;
public class CompositeIcon implements Icon{
private ArrayList<Icon> icons;
private int size;
public CompositeIcon() {
icons = new ArrayList<Icon>();
}
public void paintIcon(Component c, Graphics g, int x, int y) {
int position = x;
for(Icon z : icons) {
z.paintIcon(c,g,position,y);
position = position + z.getIconWidth();
}
}
public int getIconHeight() {
return size;
}
public int getIconWidth() {
int total = 0;
for(Icon z : icons) {
total = total + z.getIconWidth();
}
return total;
}
public void addIcon(Icon z) {
icons.add(z);
}
}
SquareIcon class is only a simple little class that creates a square of a single color with a given size.
My question is, in my ThreeColorButton class, when I run it, it doesn't show any icons when I press either of the RGB buttons. However, in the buttonListener method, if I set label.setIcons(icons) to label.setIcons(icon), it shows a single square and it doesnt place it side by side.
I can't seem to figure out whats causing this behavior. Is there a problem with displaying an array of icons using JLabel?
There is nothing to paint in the label since the height of your Icon is 0, since you never set the size.
I would suggest code something like:
#Override
public int getIconHeight()
{
int size = 0;
for(Icon z : icons)
{
size = Math.max(size, z.getIconHeight());
}
return size;
}
You may want to check out Compound Icon. Similar to your class but it has more features. It supports horizontal/vertical/stacked icon and icon alignment options.
It doesn't support dynamically adding Icons so you would need to change that. I might looking adding that feature myself (when I get time) :)
I can't seem to figure out whats causing this behavior. Is there a problem with displaying an array of icons using JLabel?
Yes, as #mKorbel mentioned, there is a problem. A JLabel can only display a single icon. If you want to display n icons, you will need n JLabel instances.
I have been breaking my head for days over a project I have to do in my Java beginner class about GUI BorderLayout Jbutton and I really hope some one here can help me out to understand it or shed some light. My task is to create a BorderLayout window with 4 button left right up and down
Each button moves the window/ Borderlayout 20 pixel left or right or up or down.
I have already created a code with the buttons but I do not to know how to make the buttons move and above all I must not allow the Window to move out/ disappear from the desktop. Please be patient with me I am totally fresh student.
Here is my code so far:
import java.awt.*;
import javax.swing.*;
public class WindowBorder extends JFrame {
private static final long serialVersionUID = 1L;
private int x, y; //the coordinates for moving in the screen
public WindowBorder (String titel){
super (titel);
//create the buttons and the layout and add the buttons
JButton right = new JButton ("Right");
JButton left = new JButton ("Left");
JButton up = new JButton ("Up");
JButton down = new JButton ("Down");
//JButton center = new JButton ("Default"); hide the middle button
setLayout (new BorderLayout (75,75));
add(BorderLayout.EAST,right);
add(BorderLayout.WEST,left);
add(BorderLayout.NORTH,up);
add(BorderLayout.SOUTH,down);
//add(BorderLayout.CENTER,default); hide the middle button
//I must create the inner class with the constructors for the task project for school
class WindowBorderInner implements ActionListener {
#Override
public void actionPerformed (ActionEvent e){
if(e.getActionCommand().equals("right"))
//this is the part that I am lost :(
}
}
//configuration the size and the location of the Border layout
setSize (400,400);
setLocationByPlatform (true);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String [] arg){ //the test method
new WindowBorder("Move Window");
}
}
I'm on my mobile so I can't(won't) type out much code, but I copied this out of another thread
jFrame.setLocation(jFrame.getX() + 5, jFrame.getY());
You can manually set the location of the JFrame in this way when the action listener is called.
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int x = (screenSize.width); int y = (screenSize.height);
class ListenerInnerClass implements ActionListener {
#Override
public void actionPerformed (ActionEvent e){
if (e.getActionCommand ().equals("Right"))
Toolkit.getDefaultToolkit().getScreenSize();
setLocation (+20,y);
}
}
public MoveBorderDemo (String titel){
super (titel);
//create the buttons and the layout and add the buttons
JButton Right = new JButton ("Right");
JButton Left = new JButton ("Left");
JButton Up = new JButton ("Up");
JButton Down = new JButton ("Down");
Right.addActionListener(new ListenerInnerClass());
setLayout (new BorderLayout (75,75));
add(BorderLayout.EAST,Right);
add(BorderLayout.WEST,Left);
add(BorderLayout.NORTH,Up);
add(BorderLayout.SOUTH,Down);
//configuration the size and the location of the Border layout
setSize (400,400);
//Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setLocation(200,200);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String [] arg){ //the test method
new MoveBorderDemo ("Move Window");
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension d = tk.getScreenSize();
System.out.println("Screen width = " + d.width);
System.out.println("Screen height = " + d.height);
}
}
I am trying to have a textfield and graphics in the same jframe but it is not working properly. I want to have the textfield in the bottom and the rest of the jframe for the graphics instead when I run it the textfield acts weirdly and covers up the entire area. Does anybody know how I can get it to work how I want it?
package pack;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class gui extends JPanel implements Runnable{
Thread t = new Thread(this);
protected JTextField textField;
private final static String newline = "\n";
public int x;
public int y;
public static void main(String args[])
{
new gui();
new input();
}
public void input()
{
textField = new JTextField(20);
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridwidth = 500;
c.gridheight = 100;
c.fill = GridBagConstraints.HORIZONTAL;
add(textField, c);
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;
}
public void actionPerformed(ActionEvent evt) {
String text = textField.getText();
textField.selectAll();
}
public gui()
{
textField = new JTextField(20);
JFrame f = new JFrame("lol");
System.out.println("::");
f.setTitle("Basic window");
f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.add(this);
f.setVisible(true);
f.setFocusable(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(textField);
run();
}
public void run()
{
while(true)
{
try
{
t.sleep(10);
}
catch(Exception e){}
System.out.println(":D");
x++;
y++;
repaint();
}
}
public void paint (Graphics g)
{
g.setColor(Color.red);
}
}
Delete this class and start fresh with a new class. The structure of the code is wrong , the class names are wrong, the custom painting is wrong, the use of Threads is wrong, the new input() doesn't do anything, you should not be using Thread.sleep(), you should not override paint(), you should not add a component to the frame after the frame is visible.
Start by reading the section from the Swing tutorial on Custom Painting. There you will find a working example that will show you how to better structure you class when doing custom painting. Use this demo code as the starting point for your program and make changes (one at a time) to this working code.
Then you can change that code and add a JTextField to the frame. You will also need to read the Swing tutorial on Using Layout Managers, to understand how a BorderLayout works. So start with something simple that works and then add extra components. Don't try to do it all at one time.
Things that you are doing in wrong way.
JFrame by default has uses BorderLayout and you are adding two components in the center hence only last components are visible.
You are adding JTextField inside JFrame as well as JPanel. Don't know why?
Use BorderLayout.SOUTH to add the JTextField in the south and don't add it into JPanel as shown below:
public gui() {
...
textField = new JTextField(20);
JFrame f = new JFrame("lol");
f.add(this);
f.add(textField, BorderLayout.SOUTH);
...
}
Please read below post once again.
How to Use GridLayout
How to Use GridBagLayout
Good day.
I develop program which must show few shapes when user clicks the button. At least it doesn't show it. What is wrong?
Code is:
public class ShowFrame extends JFrame
{
public ShowFrame()
{
this.setTitle("Show data"); //Title
this.setSize( DEF_WIDTH, DEF_HEIGHT ); //Size of frame
this.setResizable(false);
//...
JButton testButton = new JButton("Test");
buttonPanel.add(testButton);
this.add(buttonPanel, BorderLayout.SOUTH);
testButton.addActionListener( new ActionListener() { //Add listener
public void actionPerformed(ActionEvent e) {
DrawStuff stuff = new DrawStuff(); //Create class which draws shapes
add(stuff, BorderLayout.CENTER);
System.out.println("Test Button");
}
} );
}
public static final int DEF_WIDTH = 600;
public static final int DEF_HEIGHT = 400;
private JPanel buttonPanel = new JPanel();
}
Class which draws shapes:
public class DrawStuff extends JComponent
{
public void paintComponent( Graphics g )
{
Graphics2D g2 = (Graphics2D) g;
//...
Rectangle2D rect = new Rectangle2D.Double(leftX, topY, width, height);
Line2D line = new Line2D.Double(leftX, topY, 0, 0);
//...
g2.draw(rect);
g2.draw(line);
//...
}
}
When you add/remove components on a visible GUI the code should be:
panel.add(...);
panel.revalidate();
panel.repaint();
Your design of adding a new panel every time you click a button is not a very good one.
Instead you should create a custom painting panel and override the paintComponent() method. Then when you click a button you invoke a method in your custom component to set the shape you want to draw. The paintComponent() method should be smart enought to paint the shape. Then you invoke repaint() on the panel.
Read the section from the Swing tutorial on Custom Painting for more information and working examples.