Swing でカスタムまたは既製のコントロールに変換を適用することは可能ですか? 一方では変換が許可されていますが、他方では、おそらく実装にいくつかのギャップがあります。
注意問題は、変換を使用する方法ではなく、コントロールの親から変換を適用する方法に関するものです。つまり、変換は親によって発行される必要がありますが、子はそれに従う必要があります。標準の Swing コントロールを変換する方法、または PARENT 変換に従うカスタム コントロールを作成する方法を教えてください。
子を描画する前に変換を適用Graphics
し、機能しない簡単な例:
public class Tester_TransformDuringPaint_01 {
private static Logger log = LoggerFactory.getLogger(Tester_TransformDuringPaint_01.class);
private static class JPanelEx extends JPanel {
private AffineTransform transform = new AffineTransform();
public AffineTransform getTransform() {
return transform;
}
public void setTransform(AffineTransform transform) {
this.transform = transform;
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
AffineTransform savedTransform = g2.getTransform();
g2.transform(transform);
super.paintComponent(g);
g2.drawOval(0, 0, 100, 100);
g2.setTransform(savedTransform);
}
@Override
protected void paintChildren(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
AffineTransform savedTransform = g2.getTransform();
g2.transform(transform);
super.paintChildren(g);
g2.setTransform(savedTransform);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JButton button = new JButton("Button");
button.setBounds(0,20,100,60);
JPanelEx panel = new JPanelEx();
panel.setLayout(null);
panel.setBounds(10, 10, 640, 480);
panel.setBackground(Color.PINK);
panel.setTransform(AffineTransform.getScaleInstance(2, 1));
panel.add(button);
JFrameEx frame = new JFrameEx();
frame.setLayout(null);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(0.5);
frame.center();
frame.setVisible(true);
}
});
}
}
以下を描画します。
ボタンの左半分は生きているように見え、大きな部分は死んでいるように見えます。
これは、API のさまざまな部分がさまざまなアプローチでボタンを描画するためです。
修正されたオライリー ハック 51
以下は @lbalazscs の例に基づいたコードで、「範囲内」であっても変換が機能しないことを示しています。
public class BackwardsJButton extends JButton {
public BackwardsJButton(String text) {
super(text);
}
public void paint(Graphics g) {
if (g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D) g;
AffineTransform savedTransform = g2.getTransform();
AffineTransform flipTrans = new AffineTransform();
double widthD = (double) getWidth();
//flipTrans.setToTranslation(widthD, 0);
//flipTrans.scale(-2.0, 1);
flipTrans.scale(0.5, 1);
g2.transform(flipTrans);
super.paint(g);
g2.setTransform(savedTransform);
} else {
super.paint(g);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
buildFrame();
}
});
}
private static void buildFrame() {
JFrame f = new JFrame("Test");
f.setLayout(new FlowLayout());
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.add(new BackwardsJButton("BackwardsJLabel"));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
出力は次のとおりです (Swing のバグはマウス ホバー コード内にあるため、表示するにはウィンドウのサイズを変更してマウスを移動する必要がある場合があります。