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. Picture 1

The desired result is shown in the figure below. Figure 2

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);
    }
}

      

+3


source to share


3 answers


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 it Border

    , and the attached one GPanel

    can safely manipulate the graphics context.

  • Until the translate()

    red dot is centered at the origin; then the translate()

    blue point is centered on the origin, but the origin has been moved.

  • Don't use setPreferredSize()

    when you really want to override getPreferredSize()

    .

  • Do not redistribute JFrame

    unnecessarily.



image

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);
        }
    }
}

      

+3


source


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);
    });
  }
}

      

+3


source


try this code:

private void doDrawing(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.translate(0, 0);
    }

      

0


source







All Articles