TitledBorder in JPanel moves when using translate () method
I created JPanel
and add it to JFrame
. JPanel
has TitledBorder
, but when I use a method translate()
like
g2.translate(getWidth() / 2, getHeight() / 2);
the entire component, including the border, is translated. The effect is shown in Figure 1.
The desired result is shown in the figure below.
The code is inserted below.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
class GPanel extends JPanel {
private void doDrawing(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.translate(getWidth() / 2, getHeight() / 2);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
class Main extends JFrame {
public Main() {
}
public static void main(String[] args) {
Main ex = new Main();
ex.setSize(new Dimension(400, 400));
GPanel panel = new GPanel();
panel.setBorder(BorderFactory.createTitledBorder("Title"));
ex.add(panel);
ex.setLocationRelativeTo(null);
ex.setVisible(true);
}
}
source to share
You called setBorder()
into an instance GPanel
and then modified the graphics context transformation in the latest implementation paintComponent()
. The border is not aware of this, so the expected result is fully expected. Instead, follow the parenting advice JComponent
for setBorder()
"place the component in JPanel
and set the border to JPanel
". An example is shown here .
In the variant below
-
The application
bPanel
now has itBorder
, and the attached oneGPanel
can safely manipulate the graphics context. -
Until the
translate()
red dot is centered at the origin; then thetranslate()
blue point is centered on the origin, but the origin has been moved. -
Don't use
setPreferredSize()
when you really want to overridegetPreferredSize()
. -
Do not redistribute
JFrame
unnecessarily.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
class GTest {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GPanel gPanel = new GPanel();
JPanel bPanel = new JPanel();
bPanel.setBorder(BorderFactory.createTitledBorder("Title"));
bPanel.add(gPanel);
f.add(bPanel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class GPanel extends JPanel {
private static final int N = 16;
private void doDrawing(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.red);
g.fillOval(-N, -N, 2 * N, 2 * N);
g2.translate(getWidth() / 2, getHeight() / 2);
g2.setPaint(Color.blue);
g.fillOval(-N, -N, 2 * N, 2 * N);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(256, 256);
}
}
}
source to share
You may need to recover the move you made while executing g2.translate(x, y);
with g2.translate(-x, -y);
:
Graphics2D g2 = (Graphics2D) g;
double x = getWidth() / 2d;
double y = getHeight() / 2d;
g2.translate(x, y);
g2.setPaint(Color.BLUE);
g2.fill(s);
g2.translate(-x, -y);
Another common way is to use a new object Graphics
, which is a copy of the GPanel object Graphics
:
Graphics2D g2 = (Graphics2D) g.create();
g2.translate(getWidth() / 2, getHeight() / 2);
g2.setPaint(Color.BLUE);
g2.fill(s);
g2.dispose();
Main2.java
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
class GPanel extends JPanel {
private final Rectangle s = new Rectangle(0, 0, 16, 16);
private void doDrawing(Graphics g) {
g.setColor(Color.RED);
g.fillRect(s.x, s.y, s.width, s.height);
// Graphics2D g2 = (Graphics2D) g;
// double x = getWidth() / 2d;
// double y = getHeight() / 2d;
// g2.translate(x, y);
// g2.setPaint(Color.BLUE);
// g2.fill(s);
// g2.translate(-x, -y);
Graphics2D g2 = (Graphics2D) g.create();
g2.translate(getWidth() / 2, getHeight() / 2);
g2.setPaint(Color.BLUE);
g2.fill(s);
g2.dispose();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
public class Main2 extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
GPanel panel = new GPanel();
panel.setBorder(BorderFactory.createTitledBorder("Title"));
JFrame ex = new JFrame();
ex.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
ex.getContentPane().add(panel);
ex.setSize(400, 400);
ex.setLocationRelativeTo(null);
ex.setVisible(true);
});
}
}
source to share