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();
}
}
Related
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!
I've searched the internet for solutions and I don't seem to find one that works for me... In case you're wondering, I'm new to Swing. So, here's the thing, JButton appears, but JTextArea doesn't. I don't know what to do to solve this... Help me out guys...
public class FrameCreation
{
public JFrame createFrame(int width, int height, String name)
{
JFrame frame = new JFrame(name);
frame.setVisible(true);
frame.setSize(width, height);
frame.setLayout(null);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.DARK_GRAY);
return frame;
}
public JButton createButton(int width, int height, int xPos, int yPos, String text)
{
JButton button = new JButton(text);
button.setBounds(xPos, yPos, width, height);
button.setBackground(Color.GRAY);
button.setForeground(Color.WHITE);
return button;
}
public JTextArea createTextArea(int width, int height, int xPos, int yPos)
{
JTextArea txt = new JTextArea();
txt.setVisible(true);
txt.setBounds(xPos, yPos, width, height);
txt.setText("Help this poor JTextArea to appear on the frame...");
return txt;
}
}
public class Main
{
public static void main(String[] args)
{
FrameCreation mainFrame = new FrameCreation();
JFrame f = new FrameCreation().createFrame(600, 600, "My Frame");
f.add(mainFrame.createButton(100, 40, 10, 10, "Click me!"));
f.add(mainFrame.createTextArea(200, 200, 390, 10));
}
}
Remove the frame.setVisible(true); from FrameCreation class, and add it f.setVisible(true); in the end of main method.
public static void main(String[] args) {
FrameCreation mainFrame = new FrameCreation();
JFrame f = new FrameCreation().createFrame(600, 600, "My Frame");
f.add(mainFrame.createButton(100, 40, 10, 10, "Click me!"));
f.add(mainFrame.createTextArea(200, 200, 390, 10));
//This new line
f.setVisible(true);
}
Found your real problem; please don't use frame.setLayout(null);. Here is a post explaining why null layout is bad. Instead I have used flow layout and it's working as it supposed to. Here is the code(I have changed them into two classes):
Main.java
import javax.swing.*;
public class Main
{
public static void main(String[] args)
{
FrameCreation mainFrame = new FrameCreation();
JFrame f = new FrameCreation().createFrame(600, 600, "My Frame");
f.add(mainFrame.createButton(100, 40, 10, 10, "Click me!"));
f.add(mainFrame.createTextArea(300, 300, 390, 10));
f.setVisible(true);
}
}
FrameCreation.java
import javax.swing.*;
import java.awt.*;
public class FrameCreation
{
public JFrame createFrame(int width, int height, String name)
{
JFrame frame = new JFrame(name);
frame.setVisible(true);
frame.setSize(width, height);
frame.setLayout(new FlowLayout());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.DARK_GRAY);
return frame;
}
public JButton createButton(int width, int height, int xPos, int yPos, String text)
{
JButton button = new JButton(text);
button.setBounds(xPos, yPos, width, height);
button.setBackground(Color.GRAY);
button.setForeground(Color.WHITE);
return button;
}
public JTextArea createTextArea(int width, int height, int xPos, int yPos)
{
JTextArea txt = new JTextArea();
txt.setBounds(xPos, yPos, width, height);
txt.setText("Help this poor JTextArea to appear on the frame...");
return txt;
}
}
Here is the output:
When you add components to a visible GUI you need to tell the frame to repaint itself.
So you need to add:
f.revalidate();
f.repaint();
at the end of the main() method.
However, this is NOT the proper solution and is should not be used. You need to redesign your class.
I'm new to Swing
There are too many things wrong with the code to list here. So instead I suggest you start by reading the Swing Tutorial for Swing basics.
Maybe start with the section on How to Use Text Areas. The TextDemo will show you how to better structure your code so that you:
create the Swing components on the Event Dispatch Thread.
create the JTextArea with a reasonable size
use layout managers.
pack() the frame and use setVisible( true ) AFTER all components have been added to the frame.
I am making a GUI that has Graphics2D objects drawn on a JPanel within a JFrame. When I resize the window the Graphics2D objects reduce into a tiny rectangle. How can I set the drawing to resize with the JFrame when the user resizes the window?
I have tried using gridlayout, flowlayout, borderlayout, and settled on gridbaglayout. This helps with the resizing of btnPanel and the JButton but not for the Graphics2D objects.
Here is my self contained example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class DrawPanelMain extends JPanel {
/*
* Variables used to set the value of preferred height and width
*/
public static final double version = 0.0;
JPanel btnPanel = new JPanel();
JPanel switchPanel = new JPanel();
DrawEllipses drawEllipses = new DrawEllipses(POINT_LIST);
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
initializePointList();
createAndShowGui();
}
});
}
public static java.util.List<Point> POINT_LIST = new ArrayList<>();
/*
* This loop will initialize POINT_LIST with the set of points for drawing the ellipses.
* The for each loop initializes points for the top row and the second for loop draws the
* right triangle.
*/
public static void initializePointList() {
int ellipsePointsYCoordinate[] = {140, 200, 260, 320, 380, 440, 500, 560, 620};
int ellipsePointsXCoordinate[] = {140, 200, 260, 320, 380, 440, 500, 560, 620, 680};
int xx = 80;
for (int aXt : ellipsePointsXCoordinate) {
POINT_LIST.add(new Point(aXt, xx));
}
for (int i = 0; i < ellipsePointsYCoordinate.length; i++) {
for (int j = i; j < ellipsePointsYCoordinate.length; j++) {
POINT_LIST.add(new Point(ellipsePointsXCoordinate[i], ellipsePointsYCoordinate[j]));
}
}
}
public DrawPanelMain() {
switchPanel.setBorder(BorderFactory.createLoweredSoftBevelBorder());
switchPanel.setBackground(Color.DARK_GRAY);
switchPanel.add(drawEllipses);
switchPanel.revalidate();
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
// first column
c.gridx = 0;
add(switchPanel, c);
// second column
c.gridx = 1;
add(switchPanel, c);
// first row
c.gridy = 0;
// second row
c. gridy = 1;
add(btnPanel, c);
btnPanel.add(new JButton(new AddSwitchAction("Add Switch Panel")));
}
public static void createAndShowGui() {
JFrame frame = new JFrame("RF Connection Panel " + version);
frame.setLayout(new BorderLayout());
frame.add(new DrawPanelMain());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(false);
//frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
/*
* AddSwitchAction will add a new pane to the tabbedPane when the add switch button is clicked
*/
private class AddSwitchAction extends AbstractAction {
public AddSwitchAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
String title = "Switch ";
DrawEllipses tabComponent = new DrawEllipses(POINT_LIST);
switchPanel.add(title, tabComponent);
}
}
}
#SuppressWarnings("serial")
class DrawEllipses extends JPanel {
private final int PREF_W = 750; //Window width
private final int PREF_H = 750; //Window height
private final int OVAL_WIDTH = 30;
private static final Color INACTIVE_COLOR = Color.RED;
private static final Color ACTIVE_COLOR = Color.green;
private java.util.List<Point> points;
private java.util.List<Ellipse2D> ellipses = new ArrayList<>();
private Map<Ellipse2D, Color> ellipseColorMap = new HashMap<>();
/*
* This method is used to populate "ellipses" with the initialized ellipse2D dimensions
*/
public DrawEllipses(java.util.List<Point> points) {
this.points = points;
for (Point p : points) {
int x = p.x - OVAL_WIDTH / 2;
int y = p.y - OVAL_WIDTH / 2;
int w = OVAL_WIDTH;
int h = OVAL_WIDTH;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
ellipses.add(ellipse);
ellipseColorMap.put(ellipse, INACTIVE_COLOR);
}
MyMouseAdapter mListener = new MyMouseAdapter();
addMouseListener(mListener);
addMouseMotionListener(mListener);
}
/*
* paintComponent is used to paint the ellipses
*/
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (Ellipse2D ellipse : ellipses) {
g2.setColor(ellipseColorMap.get(ellipse));
g2.fill(ellipse);
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(2));
g2.draw(ellipse);
}
/*
* Set the font characteristics, color, and draw the row labels.
*/
g.setFont(new Font("TimesRoman", Font.BOLD, 18));
g.setColor(Color.BLACK);
//Along the top row
g.drawString("External Port", 10, 50);
g.drawString("1", 135, 50);
g.drawString("2", 195, 50);
g.drawString("3", 255, 50);
g.drawString("4", 315, 50);
g.drawString("5", 375, 50);
g.drawString("6", 435, 50);
g.drawString("7", 495, 50);
g.drawString("8", 555, 50);
g.drawString("9", 615, 50);
g.drawString("10", 672, 50);
//Along the Y-axis
g.drawString("Radio 2", 40, 145);
g.drawString("3", 90, 205);
g.drawString("4", 90, 265);
g.drawString("5", 90, 325);
g.drawString("6", 90, 385);
g.drawString("7", 90, 445);
g.drawString("8", 90, 505);
g.drawString("9", 90, 565);
g.drawString("10", 90, 625);
//Along the X-Axis
g.drawString("1", 135, 670);
g.drawString("2", 195, 670);
g.drawString("3", 255, 670);
g.drawString("4", 315, 670);
g.drawString("5", 375, 670);
g.drawString("6", 435, 670);
g.drawString("7", 495, 670);
g.drawString("8", 555, 670);
g.drawString("9", 615, 670);
//Draws a 3DRect around the top row of ellipse2D objects
g2.setColor(Color.lightGray);
g2.draw3DRect(120, 60, 580, 40, true);
g2.draw3DRect(121, 61, 578, 38, true);
g2.draw3DRect(122, 62, 576, 36, true);
}
/*
* MouseAdapter is extended for mousePressed Event that detects if the x, y coordinates
* of a drawn ellipse are clicked. If the color is INACTIVE it is changed to ACTIVE and
* vice versa.
*/
private class MyMouseAdapter extends MouseAdapter {
#Override
/*
* When mousePressed event occurs, the color is toggled between ACTIVE and INACTIVE
*/
public void mousePressed(MouseEvent e) {
Color c;
for (Ellipse2D ellipse : ellipses) {
if (ellipse.contains(e.getPoint())) {
c = (ellipseColorMap.get(ellipse) == INACTIVE_COLOR) ? ACTIVE_COLOR : INACTIVE_COLOR;
ellipseColorMap.put(ellipse, c);
}
}
repaint();
}
}
/*
* This method will set the dimensions of the JFrame equal to the preferred H x W
*/
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
/*
* Used for button click action to change all ellipses to ACTIVE_COLOR
*/
public void activateAll(){
for (Ellipse2D ellipse : ellipses){
ellipseColorMap.put(ellipse, ACTIVE_COLOR);
}
repaint();
}
/*
* Used for button click action to change all ellipses to INACTIVE_COLOR
*/
public void deactivateAll(){
for (Ellipse2D ellipse : ellipses){
ellipseColorMap.put(ellipse, INACTIVE_COLOR);
}
repaint();
}
}
This method will set the dimensions of the JFrame equal to the preferred H x W
No it set the preferred size of the panel. The size of the frame will be the preferred size of all the components added to it plus the frame decorations (title bar, borders).
When I resize the window the Graphics2D objects reduce into a tiny rectangle.
The GridBagLayout respects the preferred size of the component. When there is not enough space to display the component it will shrink to its "minimum size".
You probably need to override the getMinimumSize() method to equal the preferred size. Then in this case the component should just be truncated if space is not available.
If you want you actually painting to shrink then you need to build the logic into your painting code so that the painting is done relative to the space available on the panel.
Try adding your 2D object to a JLabel as BufferedImage of ImageIcon. You can do this by:
JLabel label2 = new JLabel(new ImageIcon(//Location of your Image);
Or I think you can also add Graphics2D objects directly creating them inside label bu I'm not sure about that
I'm making a score-keeping program, but I'm running into a problem. What I've tried to do is have a JPanel at the top that contains two JPanels, which, in turn, contains two team names. I'm confused as to why the two JLabels at the top of the program aren't centered inside of the JPanels they're contained in.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ScoreFrame extends JFrame {
private static final Dimension SCREEN_SIZE = Toolkit.getDefaultToolkit().getScreenSize();
private static final int WIDTH = SCREEN_SIZE.width;
private static final int HEIGHT = SCREEN_SIZE.height;
private final JTextField[] nameField = new JTextField[] { new JTextField(), new JTextField() };
private final JLabel[] nameLabel = new JLabel[] { new JLabel("Team 1"), new JLabel("Team 2") };
private final GridBagLayout gridBag = new GridBagLayout();
private final GridBagConstraints constraints = new GridBagConstraints();
private final JPanel topPanel = new JPanel();
public ScoreFrame() {
super();
setResizable(false);
setSize(SCREEN_SIZE);
setLayout(gridBag);
setUndecorated(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(new EscapeListener());
addComponents();
}
private void addComponents() {
addToTopPanel();
constraints.insets = new Insets(0, 0, (int) (HEIGHT * (double) 4 / 5), 0);
gridBag.setConstraints(topPanel, constraints);
add(topPanel);
}
private void addToTopPanel() {
final JPanel[] teamPanel = new JPanel[] { new JPanel(), new JPanel() };
topPanel.setLayout(gridBag);
topPanel.setSize(new Dimension(WIDTH, HEIGHT / 5));
Dimension teamPanelSize = new Dimension(WIDTH / 2, HEIGHT / 5);
teamPanel[0].setSize(teamPanelSize);
teamPanel[1].setSize(teamPanelSize);
Font nameFont = new Font("Times New Roman", Font.PLAIN, 50);
nameLabel[0].setFont(nameFont);
nameLabel[1].setFont(nameFont);
teamPanel[0].add(nameLabel[0]);
teamPanel[1].add(nameLabel[1]);
gridBag.setConstraints(teamPanel[0], constraints);
constraints.gridx = 1;
gridBag.setConstraints(teamPanel[1], constraints);
topPanel.add(teamPanel[0]);
topPanel.add(teamPanel[1]);
}
public void paint(Graphics g) {
super.paint(g);
int strokeSize = ((WIDTH + HEIGHT) / 2) / 300;
if (strokeSize < 1) {
strokeSize = 1;
}
final int fontSize = (int) (strokeSize * 12.5);
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(strokeSize));
g.drawLine(WIDTH / 2, 0, WIDTH / 2, HEIGHT / 5);
g.drawLine(WIDTH / 2, (int) (HEIGHT * (double) 105 / 400), WIDTH / 2, HEIGHT);
g.drawLine(0, HEIGHT / 5, WIDTH, HEIGHT / 5);
g.drawRect((int) (WIDTH * (double) 45 / 100), HEIGHT / 5, WIDTH / 10, (int) (HEIGHT * (double) 3 / 20));
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setFont(new Font("Times New Roman", Font.PLAIN, fontSize));
g.drawString("Errors", (int) (WIDTH * (double) 101 / 220), HEIGHT / 4);
}
private JFrame getFrame() {
return this;
}
public static void main(final String args[]) {
new ScoreFrame().setVisible(true);
}
public class EscapeListener implements KeyListener {
public void keyPressed(final KeyEvent event) {
if (event.getKeyCode() == 27) {
final int choice = JOptionPane.showConfirmDialog(getFrame(), "Do you want to exit the program?");
if (choice == 0) {
System.exit(0);
}
}
}
public void keyReleased(final KeyEvent event) {
}
public void keyTyped(final KeyEvent event) {
}
}
}
Invoking pack() is a critical step in using layouts. This example uses JLabel.CENTER and GridLayout to center the labels equally as the frame is resized. For simplicity, the center panel is simply a placeholder. This somewhat more complex example uses a similar approach along with java.text.MessageFormat.
Addendum: But how would I apply pack() to my code?
Simply invoke pack() as shown in the examples cited. I don't see an easy way to salvage your current approach of setting sizes extrinsically. Instead, override getPreferredSize() in a JPanel for your main content. No matter the screen size, your implementation of paintComponent() should adapt to the current size, for example.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/** #see https://stackoverflow.com/a/14422016/230513 */
public class Scores {
private final JLabel[] nameLabel = new JLabel[]{
new JLabel("Team 1", JLabel.CENTER),
new JLabel("Team 2", JLabel.CENTER)};
private void display() {
JFrame f = new JFrame("Scores");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel teamPanel = new JPanel(new GridLayout(1, 0));
teamPanel.add(nameLabel[0]);
teamPanel.add(nameLabel[1]);
f.add(teamPanel, BorderLayout.NORTH);
f.add(new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
}, BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Scores().display();
}
});
}
}
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);