Rectangle does not center vertically in JPanel with GridLayout - java

as said my rectangle does not center vertically in a JPanel with GridLayout. I have 3 columns. 1st and 2nd column have JLabels and they are centered perfect, but my custom JPanel which is just a rectangle does not. It's y coordinate is always on top of the grid's row.
public class CustomJPanel {
/**
* #param args
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 200);
frame.setResizable(false);
JPanel panel = new JPanel(new GridLayout(0,3));
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setBounds(10, 50, 320, 200);
scrollPane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
for(int i=0; i<3; i++){
JLabel nameLabel = new JLabel("Test"+i);
JLabel timeLabel = new JLabel();
timeLabel.setText("0h 0m 0s");
panel.add(nameLabel);
panel.add(timeLabel);
panel.add(new Bar());
}
frame.add(scrollPane);
frame.setVisible(true);
}
private static class Bar extends JPanel {
int width = 100;
Dimension maxDimension = new Dimension(100, 20);
#Override
public void paintComponent(Graphics g){
super.paintComponents(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLUE);
g2.fillRect(0, 0, width, 5);
}
#Override
public Dimension getMaximumSize() {
return maxDimension;
}
#Override
public Dimension getPreferredSize(){
return this.getMaximumSize();
}
}
}
Do I have to add other methods to my Bar class?
Thank you :)

That happens because you draw rectangle from y=0, but you need to draw that at the middle of your panel. You can fill rectanle in the middle like next :
g2.fillRect(0, getSize().height/2, width, 5);

Related

Drawing Circles on random JPanels by Pressing a JButton

I got a grid with JPanels, by pressing the Button on top I want a random generator to draw circles on 3 random Panels.
In theory I think I have to overwrite the PaintComponent of every JPanel with a circle, put the flag on false and when I press the button an action listener puts the flag of 3 random JPanels on true.
But I really have no idea how to do this. Is it possible to do it this way ? if yes, could you show me how, if no, could you tell me what else i have to do ? Thanks a lot. Here's my code so far:
package feld;
import javax.swing.*;
import java.awt.*;
public class Spielplan {
public static void main(String[] args) {
JFrame f1 = new JFrame();
f1.setLayout(new BorderLayout());
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setPreferredSize(new Dimension(800, 800));
JButton tokens = new JButton("Spielsteine setzen");
f1.add(tokens, BorderLayout.NORTH);
JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(3,3));
f1.add(p1, BorderLayout.CENTER);
JPanel g1 = new JPanel();
g1.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g1.setPreferredSize(new Dimension(100, 100));
g1.setVisible(true);
p1.add(g1);
JPanel g2 = new JPanel();
g2.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g2.setPreferredSize(new Dimension(100, 100));
g2.setVisible(true);
p1.add(g2);
JPanel g3 = new JPanel();
g3.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g3.setPreferredSize(new Dimension(100, 100));
g3.setVisible(true);
p1.add(g3);
JPanel g4 = new JPanel();
g4.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g4.setPreferredSize(new Dimension(100, 100));
g4.setVisible(true);
p1.add(g4);
JPanel g5 = new JPanel();
g5.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g5.setPreferredSize(new Dimension(100, 100));
g5.setVisible(true);
p1.add(g5);
JPanel g6 = new JPanel();
g6.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g6.setPreferredSize(new Dimension(100, 100));
g6.setVisible(true);
p1.add(g6);
JPanel g7 = new JPanel();
g7.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g7.setPreferredSize(new Dimension(100, 100));
g7.setVisible(true);
p1.add(g7);
JPanel g8 = new JPanel();
g8.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g8.setPreferredSize(new Dimension(100, 100));
g8.setVisible(true);
p1.add(g8);
JPanel g9 = new JPanel();
g9.setBorder(BorderFactory.createLineBorder(Color.BLACK));
g9.setPreferredSize(new Dimension(100, 100));
g9.setVisible(true);
p1.add(g9);
f1.pack();
f1.setVisible(true);
}
}
The simplest way I could think of is to create s subclass of JPanel with a boolean to determine whether the circle should be drawn. I named it CirclePanel:
public class CirclePanel extends JPanel{
public static final Color circleColor = Color.BLACK;
private boolean drawCircle;
public CirclePanel() {
drawCircle=false;
setBorder(BorderFactory.createLineBorder(Color.BLACK));
setBackground(Color.WHITE);
}
public void setDrawCircle(boolean drawCircle) {
this.drawCircle = drawCircle;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if(drawCircle) {
Graphics2D g2d = (Graphics2D) g;
Color tmp = g2d.getColor();
g2d.setColor(circleColor);
g2d.fillOval(0, 0, getWidth(), getHeight());
g2d.setColor(tmp);
}
}
}
Then I created a subclass of JFrame for the frame but you could also do it in a main method. I placed the circle panels in an array to avoid repeating code and placed them in a grid. When the button is clicked, a List of indices are created and three are removed at random. The list is then used to set the boolean variable of the panels. see below:
public class CircleGrid extends JFrame implements ActionListener{
private CirclePanel[] panels;
private JButton button;
public CircleGrid() {
super("Circle test");
setLayout(new BorderLayout());
panels = new CirclePanel[9];
JPanel center = new JPanel();
center.setLayout(new GridLayout(3, 3));
for (int i = 0; i < panels.length; i++) {
panels[i] = new CirclePanel();
center.add(panels[i]);
}
button = new JButton("Color in");
button.addActionListener(this);
this.add(button, BorderLayout.NORTH);
this.add(center, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(800, 800));
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(button)) {
// select three random circle indices -
// https://stackoverflow.com/a/42353488/7015661
ArrayList<Integer> indices = new ArrayList<Integer>();
int numRandom = 3; // three indices
for (int i = 0; i < panels.length; i++) {
indices.add(i);
}
Random r = new Random();
for (int i = 0; i < numRandom; i++) {
int rndPos1 = r.nextInt(indices.size());
indices.remove(rndPos1); // remove three indices from the list
}
// change panel boolean
for (int i = 0; i < panels.length; i++) {
CirclePanel pi = panels[i];
if(indices.contains(i)) {
// no circle
pi.setDrawCircle(false);
}else {
//draw circle
pi.setDrawCircle(true);
}
}
repaint(); // redraw panels
}
}
public static void main(String[] args) {
new CircleGrid();
}
}
I end up with the following:
What you would do is essentially before your draw on your jPanel white out the entire panel then draw your circle apply the code below hopes in helps.
int name=(int) Math.random() * 100;
int name1=(int) Math.random() * 100;
Then you would draw the circle on the JPanels using the graphics method and the appropriate code. Below is the code that draws the circle in a random place:
g.draw/fillOval (name,name1,100,100);

JPanel and JFrame size not changing [duplicate]

This question already has answers here:
paintComponent not painting onto JPanel
(2 answers)
Closed 5 years ago.
I'm making a game in Java and first I didn't use a JPanel which caused flickering on repaint() and so I decided to use it. I'm not sure how to implement it in my current code. When I tried to do so all I got was a window that was as small as it gets. My original Window class code:
public class Window extends JFrame {
private double stepLen;
public Window(double stepLen) {
this.stepLen = stepLen;
this.setSize(800, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setTitle("Frogger");
this.setLayout(null);
getContentPane().setBackground(Color.black);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int x = (dim.width - this.getSize().width)/2;
int y = (dim.height - this.getSize().height)/2;
this.setLocation(x, y);
JLabel goal = new JLabel();
goal.setText("|=========|");
goal.setForeground(Color.WHITE);
goal.setFont(new Font("Seif", Font.PLAIN, 20));
add(goal);
goal.setBounds(325, -10, 600, 50);
setFocusable(true);
requestFocusInWindow();
this.setVisible(true);
}
This code works and it creates a window.
Main class:
Window window = new Window(50);
And then I tried to do it this way:
I have separate GameFrame (JFrame) and GameCanvas (JPanel) classes.
The Frame looks like this:
public class GameFrame extends JFrame{
private double stepLen;
public GameFrame() {
this.stepLen = 50;
this.setSize(800, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setTitle("Frogger");
this.setLayout(null);
this.setVisible(true);
this.getContentPane().setBackground(Color.black);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int x = (dim.width - this.getSize().width)/2;
int y = (dim.height - this.getSize().height)/2;
GameCanvas gcanvas = new GameCanvas();
this.add(gcanvas);
this.pack();
this.setLocation(x, y);
}
}
}
And the GameCanvas class
public class GameCanvas extends JPanel {
public GameCanvas() {
setDoubleBuffered(true);
JLabel goal = new JLabel();
goal.setText("|=========|");
goal.setForeground(Color.WHITE);
goal.setFont(new Font("Seif", Font.PLAIN, 20));
this.add(goal);
goal.setBounds(325, -10, 600, 50);
this.getPreferredSize();
this.setVisible(true);
this.repaint();
}
Camickr is correct - go up vote and mark his answer as correct, this is only here to save him from pulling out what little hair he has remaining
You're using a null layout, without taking over its responsibility
Failed to provide sizing hints to for the component to allow the layout manager (which you're no longer using) to do it's job
This are all common mistakes, to which there are countless answers already provided
GameFrame
public class GameFrame extends JFrame {
private double stepLen;
public GameFrame() {
this.stepLen = 50;
this.setSize(800, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setTitle("Frogger");
// Well, there's your problem...
//this.setLayout(null);
// Don't do this here...
this.setVisible(true);
this.getContentPane().setBackground(Color.black);
// Simpler way to achieve this
//Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
//int x = (dim.width - this.getSize().width) / 2;
//int y = (dim.height - this.getSize().height) / 2;
GameCanvas gcanvas = new GameCanvas();
this.add(gcanvas);
this.pack();
//this.setLocation(x, y);
setLocationRelativeTo(null);
setVisible(true);
}
}
GameCanvas
public class GameCanvas extends JPanel {
public GameCanvas() {
// Pointless
//setDoubleBuffered(true);
JLabel goal = new JLabel();
goal.setText("|=========|");
goal.setForeground(Color.WHITE);
goal.setFont(new Font("Seif", Font.PLAIN, 20));
this.add(goal);
// Pointless
//goal.setBounds(325, -10, 600, 50);
// Pointless
//this.getPreferredSize();
// Pointless
//this.setVisible(true);
// Pointless
//this.repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
public void paintComponent(Graphics g) {
int firstRoad = 5;
int i = 0;
int max = 10;
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
g2.setColor(Color.WHITE);
g2.drawRect(5, 30, 75, 40);
while (i < max) {
g2.setColor(Color.WHITE);
g2.setStroke(new BasicStroke(3));
if (i % 2 == 0) {
g.setColor(Color.WHITE);
g.drawRect(3, firstRoad + 50 * i, 793, 50);
//g.fillRect(3, firstRoad + 50 * i, 793, 50);
} else {
g2.setColor(Color.WHITE);
g2.drawRect(3, firstRoad + 50 * i, 793, 50);
}
i++;
}
}
}
So, the way I was taught in my AP Computer Science class is to set your frame size and other frame characteristics in your main. Here is an example:
import javax.swing.JFrame;
public class theSetupClass{
public static void main(String[] args){
JFrame theGUI = new JFrame();
theGUI.setSize(300,400); //Sets the frame size to 300 by 400
theGUI.setTitle("Example");
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theComponentClass component = new theComponentClass(); //Create new theComponentClass
frame.add(component);//Add theComponentClass to theGUI
frame.setVisible(true);
}
}
The code above creates the JFrame and adds the following class to it.
import java.awt.*;
import javax.swing.*;
public class theComponentClass extends JComponent{
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
Rectangle r = new Rectangle(10,10,this.getWidth()-10,this.getHeight()-10);
//Creates a rectangle that is 10 pixels away from all sides of the frame
g2.fill(r); //Draws and fills the rectangle
}
}
I hope that you find this helpful!

Simple rectangle pattern with graphics in java

So basically when I try to increase the number of the variable which increases the number of rectangles, it starts to overlap. At the moment when i increase the variable to 2, the first column duplicates on top of the second and the second columns duplicates to the third spot where the first column duplicate should be. I'm sure it has an easy fix. I have a feeling that i need to add something to the coordinates but i'm not sure what exactly. Heres the code
public class Pattern extends JComponent implements ActionListener{
JPanel panel = new JPanel(new GridLayout(4, 4));
int width = 100;
int height = 100;
int number = 1;
JTextField tf = new JTextField(String.valueOf(width));
JTextField kl = new JTextField(String.valueOf(height));
JColorChooser color = new JColorChooser();
JCheckBox selection = new JCheckBox();
JTextField howMany =new JTextField(String.valueOf(number));
public Pattern(){
setLayout(new BorderLayout());
paneel.add(new Label("Width:"));
paneel.add(tf);
paneel.add(new Label("Height:"));
paneel.add(kl);
paneel.add(new Label("Filled in:"));
paneel.add(selection);
paneel.add(new Label("Number:"));
paneel.add(howMany);
tf.addActionListener(this);
kl.addActionListener(this);
selection.addActionListener(this);
howMany.addActionListener(this);
add(panel, BorderLayout.SOUTH);
add(color, BorderLayout.EAST);
color.setPreviewPanel(new JPanel());
}
public void paintComponent(Graphics g){
g.setColor(color.getColor());
for(int i=0; i<number; i++){
if(selection.isSelected()){
g.fillRect((width)*i, 10, width, height);
g.drawRect((width)*i, 110, width, height);
g.drawRect((width)*i+width, 10, width, height);
g.fillRect((width)*i+width, 110, width, height);
} else {
g.drawRect((width)*i, 10, width, height);
g.fillRect((width)*i, 110, width, height);
g.fillRect((width)*i+width, 10, width, height);
g.drawRect((width)*i+width, 110, width, height);
}
}
}
public static void main(String[] args){
JFrame window = new JFrame("Window");
window.setSize(1000, 1000);
window.getContentPane().add(new Pattern());
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(tf.getText());
System.out.println(kl.getText());
width = Integer.parseInt(tf.getText());
height = Integer.parseInt(kl.getText());
number =Integer.parseInt(howMany.getText());
repaint();
}
}

Add drawing in layered plane java

i am new to swing in java. i am trying to add the drawing made by the paintComponent() method in my a frame through layeredPane but it is not showing in the JFrame
However if i place the code frame.getContentPane().add(drawing) and comment the Layered part the code works..
what i am doing wrong?
here is the code:
frame class
public class FrameTest extends JFrame {
static JFrame frame= new JFrame("Frame");
public static void main(String[] args) {
FrameTest test= new FrameTest ();
}
public FrameTest (){
this.openfrane();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public void openframe(){
//window properties
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setSize(1000,600);
frame.setResizable(false);
//changing icon of window
ImageIcon image = new ImageIcon("assets/icon.png");
card.setIconImage(image.getImage());
//label picture background
JLabel background = new JLabel();
ImageIcon back = new ImageIcon("assets/background.jpg");
background.setIcon(back);
background.setLocation(0,-125);
background.setSize(1000,700);
//label for first
JLabel first = new JLabel("Sample text");
first.setForeground(Color.RED);
first.setSize(500,200);
first.setLocation(31, 150);
Draw drawing = new Draw();
JLayeredPane layers = new JLayeredPane();
layers.add(drawing, new Integer(3));
layers.add(first, new Integer(2));
layers.add(background,new Integer(1));
frame.setLayeredPane(layers);
}
}
draw class:
public class Draw extends JPanel {
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
int startX = 00;
int startY = 00;
// First circle
Ellipse2D circle1 = new Ellipse2D.Double(startX, startY, 30, 30);
g2.setColor(Color.Black);
g2.draw(circle1);
g2.fill(circle1);
// Second circle
Ellipse2D circle2 = new Ellipse2D.Double(startX+20, startY, 30, 30);
g2.setColor(Color.Black);
g2.draw(circle2);
g2.fill(circle2);
}
}
i am trying to add the drawing made by the paintComponent() method in my a frame through layeredPane but it is not showing in the JFrame
Your DrawPanel does not have a size, so the size is (0, 0) and there is nothing to paint.
However if i place the code frame.getContentPane().add(drawing) and comment the Layered part the code works..
When you add the DrawPanel directly to the content pane then the panel is added to the "CENTER" and the panel size is automatically set to the space available in the frame by the layout manager.

Adding a JPanel to a JLayeredPane causes paints and resizes to have no effect

I am trying to add a JPanel (well, several) to a JLayeredPane. However, when I do so, the paint component method of the JPanel seems to have no effect. An example is included below:
import javax.swing.*;
import java.awt.*;
public class Example {
public static void main(String[] args) {
// This Works as expected
JFrame usingPanel = new JFrame();
JPanel p = new JPanel();
p.add(new BluePanel());
usingPanel.setContentPane(p);
usingPanel.pack();
usingPanel.setVisible(true);
// This makes the frame but does not paint the BluePanel
JFrame usingLayer = new JFrame();
JLayeredPane l = new JLayeredPane();
l.setPreferredSize(new Dimension(200,200));
l.add(new BluePanel(), JLayeredPane.DEFAULT_LAYER);
JPanel p2 = new JPanel();
p2.add(l);
usingLayer.setContentPane(p2);
usingLayer.pack();
usingLayer.setVisible(true);
}
static class BluePanel extends JPanel{
public BluePanel(){
setPreferredSize(new Dimension(200,200));
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(0, 0, 200, 200);
}
}
}
Why is this? and what are the possible solutions?
JLayeredPane does not have a LayoutManager, so you need to set the location and size of your panels yourself.
See the tutorial
you hardcoded the size on the screen and have to change from
g.fillRect(0, 0, 200, 200);
to
g.fillRect(0, 0, getWidth(), getHeight());
(a minor change) add the method
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
and then remove of code line setPreferredSize(new Dimension(200,200));

Categories

Resources