JPanel 中的 TitledBorder 在使用 translate() 方法时移动
TitledBorder in JPanel moves when translate() method is used
我创建了一个 JPanel
并将其添加到 JFrame
。 JPanel
有 TitledBorder
,但是当我使用 translate()
方法时,例如
g2.translate(getWidth() / 2, getHeight() / 2);
整个组件,包括边框都已翻译。效果如图 1 所示。
期望的结果如下图所示。
代码粘贴在下面。
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);
}
}
试试这个代码:
private void doDrawing(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.translate(0, 0);
}
您已在 GPanel
的实例上调用了 setBorder()
,然后在后者的 paintComponent()
实现中修改了图形上下文的变换。边界不知道这一点,所以显示的结果完全是意料之中的。相反,请遵循 setBorder()
: "put the component in a JPanel
and set the border on the JPanel
." A related example is shown .
的父 JComponent
实施建议
在下面的变体中,
封闭的 bPanel
现在有 Border
,封闭的 gPanel
可以安全地操作图形上下文。
在translate()
之前,红点以原点为中心; translate()
后,蓝点以原点为中心,但原点移动了。
当你真的想覆盖getPreferredSize()
时,不要使用setPreferredSize()
。
不要不必要地扩展 JFrame
。
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);
}
}
}
您可能需要恢复通过执行 g2.translate(x, y);
和 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);
另一种常见的方法是使用新的 Graphics
对象,它是 GPanel 的 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);
});
}
}
我创建了一个 JPanel
并将其添加到 JFrame
。 JPanel
有 TitledBorder
,但是当我使用 translate()
方法时,例如
g2.translate(getWidth() / 2, getHeight() / 2);
整个组件,包括边框都已翻译。效果如图 1 所示。
期望的结果如下图所示。
代码粘贴在下面。
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);
}
}
试试这个代码:
private void doDrawing(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.translate(0, 0);
}
您已在 GPanel
的实例上调用了 setBorder()
,然后在后者的 paintComponent()
实现中修改了图形上下文的变换。边界不知道这一点,所以显示的结果完全是意料之中的。相反,请遵循 setBorder()
: "put the component in a JPanel
and set the border on the JPanel
." A related example is shown
JComponent
实施建议
在下面的变体中,
封闭的
bPanel
现在有Border
,封闭的gPanel
可以安全地操作图形上下文。在
translate()
之前,红点以原点为中心;translate()
后,蓝点以原点为中心,但原点移动了。当你真的想覆盖
getPreferredSize()
时,不要使用setPreferredSize()
。不要不必要地扩展
JFrame
。
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);
}
}
}
您可能需要恢复通过执行 g2.translate(x, y);
和 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);
另一种常见的方法是使用新的 Graphics
对象,它是 GPanel 的 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);
});
}
}