Why does Java Swing draw at the wrong place? - java

To be more specific I edit the question by replacing it with some reproducible code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class TestStackOverflow {
public static void main(String[] args) {
new TestStackOverflow();
}
public TestStackOverflow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame window = new JFrame();
window.setSize(new Dimension(1000, 1000));
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel header = new JPanel();
header.add(new JLabel("Hello, I'm the header"));
header.setBackground(Color.red);
window.add(header, BorderLayout.NORTH);
window.add(new TestPane());
window.setLocationRelativeTo(null);
window.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setBackground(Color.blue);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(900, 0, 100, 100);
//System.out.println(getWidth());
}
}
}
This code shows the rectangle being drawn too far right. I saw with "getWidth" that the width is actually less then 1000, but I had defined with window.setSize(new Dimension(1000, 1000)) the size of the window. So, why is it just 984 instead of 1000. The swing documentation says that the component would take the remaining space and that would / should be in my case 1000.
image of wrong placed rectangle

You seem to want it in the corner of the whole window. In that case you need to override the frame's painting method. Demo obviously - I'm not suggesting you write it exactly like this:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class TestStackOverflow {
public static void main(String[] args) {
new TestStackOverflow();
}
public TestStackOverflow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame window = new JFrame() {
#Override
public void paint(Graphics g) {
super.paint(g);
g.drawRect(900, 0, 100, 100);
// System.out.println(getWidth());
}
};
window.setSize(new Dimension(1000, 1000));
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel header = new JPanel();
header.add(new JLabel("Hello, I'm the header"));
header.setBackground(Color.red);
window.add(header, BorderLayout.NORTH);
window.add(new TestPane());
window.setLocationRelativeTo(null);
window.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setBackground(Color.blue);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//g.drawRect(900, 0, 100, 100);
// System.out.println(getWidth());
}
}
}

Related

change color of already drawn Graphics object in java AWT not working

Am trying to change color after drawing the object in window, this is what i came up with, am a beginner so this is messy.
import java.awt.*;
import java.awt.event.*;
import java.awt.event.WindowEvent;
import java.util.Arrays;
import java.util.List;
public class TestGraphic extends Figure {
TestGraphic(){
setSize(600,600);
closeFrame();
}
public static void main(String[] args) {
TestGraphic test = new TestGraphic();
test.setVisible(true);
}
public void paint(Graphics gui) {
drawComponent(gui);
}
public void drawComponent(Graphics gui) {
gui.drawOval(108,110,200,200);
gui.drawOval(160,150,20,20);
gui.drawOval(240,150,20,20);
gui.drawRect(160,220,100,40);
Button btn = new Button("Change color");
btn.setBounds(30,100,80,30);
add(btn);
changeColor(gui,btn);
}
#Override
void draw(Graphics gui) {
// TODO Auto-generated method stub
}
#Override
public boolean contains(int x, int y) {
return false;
}
private void closeFrame(){
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
}
void changeColor(Graphics gui,Button btn) {
List<Color> colorList;
colorList = Arrays.asList(Color.black, Color.blue , Color.cyan, Color.red, Color.green, Color.magenta, Color.orange, Color.yellow);
btn.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
for(int i = 0;i < colorList.size(); i++) {
gui.setColor(colorList.get(i));
}
}
});
}
}
The class Figure is an abstract class that is inheriting from java.awt.Frame
Any remarks about how to make this code cleaner will be appreciated, thanks.
Before you begin on something as complex as custom painting, make sure you have a firm understanding of the basics of the language and the APIs
See Creating a GUI With Swing, Performing Custom Painting and Painting in AWT and Swing for more details.
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 java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Color desiredColor = Color.BLACK;
private List<Color> avaliableColors = new ArrayList<>(16);
public TestPane() {
setLayout(new BorderLayout());
avaliableColors.add(Color.BLACK);
avaliableColors.add(Color.BLUE);
avaliableColors.add(Color.CYAN);
avaliableColors.add(Color.DARK_GRAY);
avaliableColors.add(Color.GRAY);
avaliableColors.add(Color.GREEN);
avaliableColors.add(Color.LIGHT_GRAY);
avaliableColors.add(Color.MAGENTA);
avaliableColors.add(Color.ORANGE);
avaliableColors.add(Color.PINK);
avaliableColors.add(Color.RED);
avaliableColors.add(Color.WHITE);
avaliableColors.add(Color.YELLOW);
JButton btn = new JButton("Change color");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Randomise the colors
Collections.shuffle(avaliableColors);
desiredColor = avaliableColors.get(0);
repaint();
}
});
add(btn, BorderLayout.SOUTH);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(desiredColor);
g2d.drawOval(108, 110, 200, 200);
g2d.drawOval(160, 150, 20, 20);
g2d.drawOval(240, 150, 20, 20);
g2d.drawRect(160, 220, 100, 40);
g2d.dispose();
}
}
}
Since you're just starting out, I might suggest getting started with JavaFX instead
AWT
!! Warning !!
No one uses AWT anymore and you're not likely to get much in the way of support for it here. This is a "basic" concept converted from the previous example, beware, AWT isn't double buffered by default
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Frame frame = new Frame();
frame.add(new TestCanvas());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestCanvas extends Container {
private Color desiredColor = Color.BLACK;
private List<Color> avaliableColors = new ArrayList<>(16);
public TestCanvas() {
setLayout(new BorderLayout());
avaliableColors.add(Color.BLACK);
avaliableColors.add(Color.BLUE);
avaliableColors.add(Color.CYAN);
avaliableColors.add(Color.DARK_GRAY);
avaliableColors.add(Color.GRAY);
avaliableColors.add(Color.GREEN);
avaliableColors.add(Color.LIGHT_GRAY);
avaliableColors.add(Color.MAGENTA);
avaliableColors.add(Color.ORANGE);
avaliableColors.add(Color.PINK);
avaliableColors.add(Color.RED);
avaliableColors.add(Color.WHITE);
avaliableColors.add(Color.YELLOW);
JButton btn = new JButton("Change color");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Randomise the colors
Collections.shuffle(avaliableColors);
desiredColor = avaliableColors.get(0);
repaint();
}
});
add(btn, BorderLayout.SOUTH);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(desiredColor);
g2d.drawOval(108, 110, 200, 200);
g2d.drawOval(160, 150, 20, 20);
g2d.drawOval(240, 150, 20, 20);
g2d.drawRect(160, 220, 100, 40);
g2d.dispose();
}
}
}

trying to display timer count, drawString method not working properly

I am trying to display a timer count, but it is not being displayed, but everything else works fine. Thank you for helping btw.
import javax.swing.*;
import java.util.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Tester {
static Timer timer;
static JFrame frame;
static JPanel panel;
public static void init(){
frame = new JFrame();
panel = new JPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(500, 500);
frame.add(panel);
}
The method above is just to make code cleaner.
public static void main(String[] args) {
init();
class Clicker extends JPanel{
int timesClicked;
public Clicker(){
timesClicked = 0;
}
void updateClicks(){
timesClicked++;
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
System.out.println("Called!!!");
g2.drawString("Half Seconds: "+timesClicked, 100, 100);
}
} //end of Clicker
drawString method not working is above.
final Clicker c = new Clicker();
panel.add(c);
class TimeChecker implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Clicked!");
c.updateClicks();
}
}// end of TimeChecker
ActionListener listener = new TimeChecker();
timer = new Timer(500,listener);
timer.start();
}
}
You have a combination of issues
Clicker was never actually added to anything
panel uses a FlowLayout by default, but Clicker provides no sizing hints, so it's sized to 0x0
You code generally is setup a little weird. I would learn to do without static very, very quickly.
Quick and fast solution...
Change the layout manager for panel to BorderLayout...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
static Timer timer;
static JFrame frame;
static JPanel panel;
public static void init() {
frame = new JFrame();
panel = new JPanel(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(500, 500);
frame.add(panel);
}
public static void main(String[] args) {
init();
class Clicker extends JPanel {
int timesClicked;
public Clicker() {
timesClicked = 0;
}
void updateClicks() {
timesClicked++;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
System.out.println("Called!!!");
g2.setColor(Color.BLACK);
g2.drawString("Half Seconds: " + timesClicked, 100, 100);
}
} //end of Clicker
final Clicker c = new Clicker();
panel.add(c);
panel.revalidate();
panel.repaint();
class TimeChecker implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Clicked!");
c.updateClicks();
}
}// end of TimeChecker
ActionListener listener = new TimeChecker();
timer = new Timer(500, listener);
timer.start();
}
}
A slightly different approach (with out static)
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.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
Clicker clicker = new Clicker();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(clicker);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
class TimeChecker implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Clicked!");
clicker.updateClicks();
}
}// end of TimeChecker
ActionListener listener = new TimeChecker();
Timer timer = new Timer(500, listener);
timer.start();
}
});
}
public class Clicker extends JPanel {
private int timesClicked;
public Clicker() {
timesClicked = 0;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 200);
}
void updateClicks() {
timesClicked++;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
System.out.println("Called!!!");
g2.setColor(Color.BLACK);
g2.drawString("Half Seconds: " + timesClicked, 100, 100);
}
}
}

JFrame, JPanel, paintComponent how to

Hi I have following classes, I want display content
(paintComponentor that panel with this rectangle from paint class)
inside my JFrame. I try already find out how to achieve this by
looking at different examples posted on this forum however this
doesn't help me I need simple example like panel inside frame with
paint component or something similar to understand how should work!
ps. don't hang me on tree because I am newbie jut ask question!!!
[I want something like this][1]
package scp;
import java.awt.*;
import javax.swing.*;
public class Panel extends JPanel {
public Panel() {
//this.setPreferredSize(new Dimension(200,200));
//panel = new Panel();
setVisible(true);
setLayout(new FlowLayout());
setSize(200, 300);
getRootPane();
}
#Override
public void paintComponent(Graphics g){
g.drawString("HEY",20,20);
g.drawRect(200, 200, 200, 200);
}
}
and
package scp;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.beans.EventHandler;
public class Frame extends JFrame {
JButton redButton;
JButton blueButton;
public Frame()
{
super("EventHandling");
setLayout(new FlowLayout());
redButton = new JButton("Red");
add(redButton);
blueButton = new JButton("Blue");
add(blueButton);
EventHandler h = new EventHandler();
redButton.addActionListener(h);
blueButton.addActionListener(h);
}
private class EventHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource()==redButton)
getContentPane().setBackground(Color.RED);
else if(e.getSource()==blueButton)
getContentPane().setBackground(Color.BLUE);
}
}
}
and
package scp;
import javax.swing.JFrame;
public class EventHandling {
public static void main(String[] args) {
Frame f = new Frame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800,600);
f.setVisible(true);
f.getContentPane().add(new Panel());
}
}
[1]: http://i.stack.imgur.com/OJTrq.png
Start by taking a look at:
Painting in AWT and Swing
Performing Custom Painting
2D Graphics
This is probably the simplest I can make it...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
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");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth() - 100;
int height = getHeight() - 100;
int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;
g2d.setColor(Color.RED);
g2d.drawRect(x, y, width, height);
g2d.dispose();
}
}
}
Compound Example
This example uses an outer panel, which has an empty border applied to it, this pushes the content of the edges of the outer panel.
The inner panel (which is unchanged from the last example), as a light gray border applied to it so you can see it, the red rectangle is still been painted by the panels paintComponent method.
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 javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JPanel outer = new JPanel(new BorderLayout()) {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
};
outer.setBorder(new EmptyBorder(50, 50, 50, 50));
TestPane tp = new TestPane();
tp.setBorder(new LineBorder(Color.LIGHT_GRAY));
outter.add(tp);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(outer);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth() - 100;
int height = getHeight() - 100;
int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;
g2d.setColor(Color.RED);
g2d.drawRect(x, y, width, height);
g2d.dispose();
}
}
}

Java graphics, making the window flash in different colors

this is my first post here. I am currently learning about basic GUI and Graphics in java. I'm still pretty new to the language, and it's my first language as well. As I learn java I like to experiment and play with the new tools I acquire from reading. As a result I wanted to make a window where the colors it is filled with will flash, currently, i wanted to stay simple and have it flash from orange to cyan and back. However, right now, all my program does is start white, and fill in with cyan and the text, and then stop changing whatsoever, and I'm not sure why this is.
Please point me in the right direction, thanks!
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class ColorFlash extends JFrame{
private static class Display extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g);
for(int h = 200; h > 25; h--){
g.setColor(Color.ORANGE);
g.fillRect(0, 0, 500, 500);
g.setColor(Color.CYAN);
g.fillRect(0, 0, 500, 500);
g.setColor(Color.ORANGE);
g.drawString("Hello world!", 30, 35);
g.drawOval(100, 100, 60, 60);
}
}
}
private static class ButtonHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
System.exit(0);
}
}
public static void main (String [] args){
Display displayPanel = new Display();
JButton okButton = new JButton("OK");
ButtonHandler listener = new ButtonHandler();
okButton.addActionListener(listener);
JPanel content = new JPanel();
content.setLayout(new BorderLayout());
content.add(displayPanel, BorderLayout.CENTER);
//content.add(okButton, BorderLayout.SOUTH);
//subContent.add(displayPanel, BorderLayout.SOUTH);
//content.add(okButton, BorderLayout.SOUTH);
content.add(okButton, BorderLayout.SOUTH);
JFrame window = new JFrame("GUI Test");
window.setContentPane(content);
window.setSize(500, 500);
window.setLocation(100,100);
window.setVisible(true);
}
}
Start by taking a look at Performing Custom Painting and Painting in AWT and Swing
Basically, what's happening is whatever is painted last in your loop is what is actually been painted to the screen
What you need is some kind of timer/trigger that can change the color you want to paint with and repaint the component.
Take a look at How to use Swing Timers for more details
For example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestPaint {
private static class Display extends JPanel {
private Color[] colors = new Color[]{Color.ORANGE, Color.CYAN};
private int colorIndex;
public Display() {
Timer timer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setBackground(colors[colorIndex % 2]);
colorIndex++;
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.ORANGE);
g.drawString("Hello world!", 30, 35);
g.drawOval(100, 100, 60, 60);
}
}
public static void main(String[] args) {
new TestPaint();
}
public TestPaint() {
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");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Display());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
You might also like to take a look at Initial Threads

Staggered Top Alignment JPanels

I am attempting to use a FlowLayout to get my panels to align vertically. I want the bottom right to align toward the bottom of the top right panel, not the bottom of that row.
Here is what I have done:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BigPanel extends JPanel {
#Override
public Component.BaselineResizeBehavior getBaselineResizeBehavior() {
return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
}
#Override
public int getBaseline(int width, int height) {
return 0;
}
public BigPanel() {
FlowLayout layout = new FlowLayout();
layout.setAlignOnBaseline(true);
this.setLayout(layout);
this.add(new Panel1()); // size: 340x, 160y
this.add(new Panel2()); // size: 340x, 120y
this.add(new Panel3()); // size: 340x, 160y
this.add(new Panel4()); // size: 340x, 300y
}
}
How can I simply anchor panels and components to a set of coordinates? I have run into this problem many times this last week and use ridiculous workarounds for my jlabels, etc.
How it looks now:
There are probably a few ways you can achieve this, but the simplest would be to use compound layouts.
Use two panels to act as the columns and then place these onto the main container. Into these you would then place you other components.
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.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class CompundLayout {
public static void main(String[] args) {
new CompundLayout();
}
public CompundLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JPanel left = new JPanel();
JPanel right = new JPanel();
setLayout(new GridLayout(0, 2, 2, 2));
left.add(createPane(Color.RED));
left.add(createPane(Color.GREEN));
right.add(createPane(Color.BLUE));
right.add(createPane(Color.MAGENTA));
add(left);
add(right);
}
protected JPanel createPane(Color color) {
SimplePane pane = new SimplePane();
pane.setBorder(new LineBorder(color));
return pane;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
public class SimplePane extends JPanel {
private int width;
private int height;
public SimplePane() {
width = 100;
height = 50 + (int) Math.round(Math.random() * 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
}
}

Categories

Resources