Ok i have a JPanel such as this one :
public class GUI {
JFrame frame = new JFrame("Net");
JPanel panel = new JPanel();
public GUI()
{
frame.setSize(835,650);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
frame.add(panel);
panel.setSize(600,600);
panel.setLocation(215,5);}
There are some other panels in there tables etc. My main is this one :
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
//new GUI();
new GUI().buildTable();
}
});
And there i another class this one :
public class DrawPlanes extends GUI
{
private static int centreX, centreY, radius;
private Color colour;
public DrawPlanes()
{
centreX = 300;
centreY = 300;
radius = 200;
colour = Color.BLACK;
}
public DrawPlanes(int centreX,int centreY, int radius, Color colour)
{
this.centreX = centreX;
this.centreY = centreY;
this.radius = radius;
this.colour = colour;
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
System.out.println("ppp");
Graphics2D g2D = (Graphics2D) g;
g2D.setStroke(new BasicStroke(2F));
g.setColor(Color.BLACK);
g.drawOval(centreX - radius , centreY - radius, radius * 2 , radius * 2);
......
}
}
Now i cant add this class to my panel i tried creating an object in main and then adding the object to my panel. I ve also tried
panel.add(new DrawPlanes(int x, int y, int radius,Color colour));
but it didnt get the drawing added in the panel.Any suggestions?
DrawPanel is not a component, it extends GUI which is not a component either.
container.add(component) function expects a Component, in Swing essentially JComponent and it's extending component: JPanel, JLabel, JButton etc.
extends DrawPanel to a JComponent or JPanel. However they both are basically some other than the fact that JComponent is non-opaque while JPanel is opaque.
Related
I try to use swing and I have a litle problem that I fail to solve. That I want to do is simple: I just want to had to JPanel in a JFrame using BorderLayout.
The problem is my center panel is always placed above my North Jpanel. In fact whatever the size I give my north panel just have like 10 pixel, after the center pannel beggin (like on this image).
Note: when I put my second panel south the first panel have enough place to be drawn but even if it has more place the second one also take just 10 pixel which is not enough (like on this image).
this is my Plateau constructor class which extends JFrame:
public Plateau(){
super("arkanoid");
this.setLayout(new BorderLayout());
setFocusable(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().add(affich,BorderLayout.NORTH);
this.getContentPane().add(jeu, BorderLayout.CENTER);
setVisible(true);
this.setResizable(false);
this.setMinimumSize(new Dimension(700,800));
this.setLocationRelativeTo(null);
}
here a part of my panel placed in center (the rest is dvariable modification and drawing functions):
public class Jeu extends JPanel {
public Jeu(int score, int plateauX, int balleX, int balleY, boolean perdu){
super();
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D)g;
this.setSize(new Dimension(Width,Heigth));
}
}
and here is all my class supposed to be on north:
public class Affich extends JPanel {
public Affich() {
super();
this.setSize(100,100);
}
public void paint(Graphics g){
this.setSize(100,100);
g.drawOval(0, 0, 50, 50);
}
}
I hope I was clear enough
NEVER call setSize(...) or anything like it within a painting method. These methods should be for painting and painting only, and if you try to change size state, you can end up with a vicious cycle of endless calls -- set size which calls repaint which sets size, which calls repaint.
Instead:
Override the JPanel's paintComponent not paint, since paint is responsible for more than painting the JPanel, and overriding it can have unintended consequences on the JPanel's borders and child components.
Call the super's paintComponent within the override
Again, do only painting within a painting method
Don't set size but instead set preferred size and from code that is called once, and not within a painting method.
For example
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
public class MyDrawing {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int affichW = 100;
int affichH = 100;
Affich affich = new Affich(affichW , affichH );
Jeu jeu = new Jeu();
frame.add(affich, BorderLayout.PAGE_START);
frame.add(jeu, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
#SuppressWarnings("serial")
class Jeu extends JPanel {
private static final int JEU_W = 600;
private static final int JEU_H = 450;
public Jeu(int score, int plateauX, int balleX, int balleY, boolean perdu) {
super();
setBorder(BorderFactory.createTitledBorder("Jeu"));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
} else {
return new Dimension(JEU_W, JEU_H);
}
}
public Jeu() {
this(0, 0, 0, 0, false);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// draw with g2 here
}
}
#SuppressWarnings("serial")
class Affich extends JPanel {
private int width = 0;
private int height = 0;
public Affich(int width, int height) {
super();
this.width = width;
this.height = height;
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
} else {
return new Dimension(width, height);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// draw smooth oval
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawOval(0, 0, 50, 50);
}
}
I've a class extending JLabel. This JLabel has a particolar shape and I draw that in the method paintComponent. I want to show a text in the center of the jLabel but this text is not shown. Could anyone help me.
My simple HLabel class in the following:
private class Scudetto extends JLabel {
private static final long serialVersionUID = 1L;
public Scudetto(String line_point)
{
super(line_point, SwingUtilities.CENTER);
this.setOpaque(true);
this.setBackground(Color.BLACK);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension d = this.getSize();
int[] x = { 0, d.width, d.width, d.width / 2, 0 };
int[] y = { 0, 0, d.height / 2, d.height, d.height / 2 };
g.setColor(Color.WHITE);
g.fillPolygon(x, y, 5);
g.setColor(Color.BLACK);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(10, 20);
}
}
I want to show a text in the center of the jLabel but this text is not shown.
The super.paintComponent() will paint the text, but then your custom painting will paint the polygon over top of the text.
Don't override the JLabel. Instead you can create a PolygonIcon. Then you add the Icon and text to the JLabel.
You can have the text centered on the label by using:
JLabel label = new JLabel("your text");
label.setIcon( polygonIcon );
label.setHorizontalTextPosition(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.CENTER);
Here is a simple example of creating a rectangular Icon:
import java.awt.*;
import javax.swing.*;
public class ColorIcon implements Icon
{
private Color color;
private int width;
private int height;
public ColorIcon(Color color, int width, int height)
{
this.color = color;
this.width = width;
this.height = height;
}
public int getIconWidth()
{
return width;
}
public int getIconHeight()
{
return height;
}
public void paintIcon(Component c, Graphics g, int x, int y)
{
g.setColor(color);
g.fillRect(x, y, width, height);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI()
{
JPanel panel = new JPanel( new GridLayout(2, 2) );
for (int i = 0; i < 4; i++)
{
Icon icon = new ColorIcon(Color.RED, 50, 50);
JLabel label = new JLabel( icon );
label.setText("" + i);
label.setHorizontalTextPosition(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.CENTER);
panel.add(label);
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(panel);
f.setSize(200, 200);
f.setLocationRelativeTo( null );
f.setVisible(true);
}
}
I'll let you modify the code for a polygon.
You can also check out Playing With Shapes for some fun ways to create an Icon of different shapes.
So, I have this simple program that allows you to click a JMenu item "New Rectangle" and it adds a shape on the center of the screen. My question is: how can I click-and-drag this around the window? I know I will need some type of Mouse Listener but I'm not sure exactly how to implement it.
public class SimpleDraw {
public static void main(String[] args) {
JFrame frame = new UMLWindow();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(30, 30, 1000, 700);
frame.getContentPane().setBackground(Color.white);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
// Display the window.
frame.setVisible(true);
}
}
class UMLWindow extends JFrame {
Squares squares = new Squares();
private static final long serialVersionUID = 1L;
public UMLWindow() {
addMenus();
}
public void addMenus() {
getContentPane().add(squares);
JMenuBar menubar = new JMenuBar();
JMenu shapes = new JMenu("Shapes");
JMenuItem rectangleMenuItem = new JMenuItem("New Rectangle");
rectangleMenuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
squares.addSquare(10, 10, 100, 100);
}
});
shapes.add(rectangleMenuItem);
menubar.add(shapes);
setJMenuBar(menubar);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
class Squares extends JPanel {
private static final long serialVersionUID = 1L;
private List<Rectangle> squares = new ArrayList<Rectangle>();
public void addSquare(int x, int y, int width, int height) {
Rectangle rect = new Rectangle(getWidth() / 2 - width / 2, getHeight()
/ 2 - height / 2, width, height);
squares.add(rect);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setOpaque(true);
this.setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle rect : squares) {
g2.draw(rect);
}
repaint();
}
}
Maybe it can help you :
http://zetcode.com/tutorials/javaswingtutorial/resizablecomponent/
Disadvantage of code
In this code we do not layout manager. So if we have a component in center of jframe when this jframe is re-sizing this component maybe display in corner of jframe. You can solve this problem but it is a little complex. We can talk about this problem if you want.
I wrote a solution for this in this package here. You can see that there is an AreaDragger class, which sounds like what you are looking for
So I am testing out a JSlider for a bigger project and can't get it to work. The slider is supposed to adjust the size of a circle, and it's not working. I thought I might have an issue with the creation of the circle, and I am trying to use setFrame, and it's giving an error saying it's "undefined." Can anyone see why? Since it should take in either float or double as parameters. Or if you can see why it's not adjusting the size of the shape that would help a lot too... Here's what I have:
public class DrawShape extends JPanel{
private float width = 300;
private Shape circle = new Ellipse2D.Float(100, 20, width, 300);
public DrawShape() {
}
public DrawShape(float width) {
this.width = width;
}
public void setWidth(int w) {
this.width = w;
circle.setFrame(100, 20, width, 300);//This is where the error is
}
public void paintComponent (Graphics g) {
super.paintComponents(g);
Graphics2D graphics = (Graphics2D)g;
graphics.setColor(Color.black);
graphics.fill(circle);
}//end paintComponent
}//end class
Class with main:
public class SliderTest extends JFrame{
private static DrawShape circle = new DrawShape();
JSlider slider;
JLabel label;
public SliderTest() {
setLayout(new FlowLayout());
slider = new JSlider(JSlider.HORIZONTAL, 150, 450, 300);//orientation, min val, max value, starting val
slider.setMajorTickSpacing(50);//every 5 integers will be a new tick position
slider.setPaintTicks(true);
add(slider);
label = new JLabel("Current value 300");
add(label);
event e = new event();
slider.addChangeListener(e);;
}//end cons
public class event implements ChangeListener{
public void stateChanged(ChangeEvent e) {
JSlider slider = (JSlider)e.getSource();
int value = slider.getValue();
label.setText("Current Value " + value);
circle.setWidth(value);
repaint();
}//end stateChanged
}//end class event
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("Circle");
frame.add(circle);
frame.setSize(500,400);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
JFrame frame1 = new SliderTest ();
frame1.setTitle("Toolbar");
frame1.setSize(300,200);
frame1.setLocation(200,100);
frame1.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame1.setVisible(true);
}
}
Shape does not have a setFrame method. RectangularShape does...
Instead of
private Shape circle = new Ellipse2D.Float(100, 20, width, 300);
You might try using...
private Ellipse2D circle = new Ellipse2D.Float(100, 20, width, 300);
instead...
Your public DrawShape(float width) { constructor is also wrong, as it does not actually do anything.
You should also consider overriding the getPreferredSize method so it can return the width of the shape as a part of the preferred size.
I'm not sure you actually need to maintain the width reference as you can ascertain this from the circle directly...IMHO
For Example
I've not tested this...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JPanel;
public class DrawShape extends JPanel {
private final Ellipse2D circle = new Ellipse2D.Float(100, 20, 300, 300);
public DrawShape() {
}
public DrawShape(float width) {
circle.setFrame(100, 20, width, 300);
}
public void setWidth(int w) {
circle.setFrame(100, 20, w, 300);
revalidate();
}
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width = circle.getBounds().width;
return size;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D graphics = (Graphics2D) g;
graphics.setColor(Color.black);
graphics.fill(circle);
}//end paintComponent
}//end class
I am extending JFrame like this:
public GameFrame() {
this.setBounds(30, 30, 500, 500);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
initializeSquares();
}
private void initializeSquares(){
for(int i = 0; i < 5; i++){
this.getContentPane().add(new Square(i*10, i*10, 100, 100));
}
this.setVisible(true);
}
However, only one square is being drawn on the screen, does anybody know why?
also My Square class looks like this:
private int x;
private int y;
private int width;
private int height;
public Square(int x, int y, int width, int height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(x, y, width, height);
}
The JFrame's contentPane uses BorderLayout by default. When you add a Square to it, it gets added by default BorderLayout.CENTER and covers up any previously added Squares. You will want to read up on all the layout managers available to Swing GUI's.
For e.g., start here: Laying Out Components within a Container
But having said this, I would do things differently. I would create just one JPanel and make it able to paint multiple squares. For example something like so:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class GameFrame extends JFrame {
public GameFrame() {
super("Game Frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Squares squares = new Squares();
getContentPane().add(squares);
for (int i = 0; i < 15; i++) {
squares.addSquare(i * 10, i * 10, 100, 100);
}
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new GameFrame();
}
}
class Squares extends JPanel {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
private List<Rectangle> squares = new ArrayList<Rectangle>();
public void addSquare(int x, int y, int width, int height) {
Rectangle rect = new Rectangle(x, y, width, height);
squares.add(rect);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle rect : squares) {
g2.draw(rect);
}
}
}
Fo absolute positioning, call setLayout(null). Then the icons will be drawed at the position returned by their getLocation() method, so you might want to call the setLocation() first.
Even I was having an issue while displaying multiple rectangles on a jframe with absolute layout i.e layout set to null.
JFrame frame = new JFrame("hello");
frame.setLayout(null);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.getContentPane().setBackground(Color.red);
frame.getContentPane().add(new Square(10,10,100,100));//My rectangle class is similar to the Square mentioned in the question and it extends JComponent.
Still I was getting issues as the rectangle was not displayed.Unless you explicitly set the bounds on the Square(JComponent) ,it will not work.Even though the Square has the location passed in the constructor ,setbounds only fixed the issue.So the below fixed the issue and this issue is for an absolute layout jframe.
Square square = new Square(10,10,100,100);
square.setBounds(10,10,100,100);
frame.getContentPane().add(square);