如果我有一个带有多个子组件的JPanel,我怎么能这样做,以便JPanel保持正方形,尽管它的父级是如何调整大小的?我尝试了以下代码的变体,但它不会导致子组件也是正方形。
public void paint(Graphics g){
if(this.isSquare()){
Dimension d = this.getSize();
if(d.height > d.width){
this.setSize(d.width, d.width);
} else {
this.setSize(d.height, d.height);
}
super.paint(g);
}
这是一个SSCCE。
包含父级:
import javax.swing.JFrame;
public class TestFrame extends JFrame{
public TestFrame(){
this.add(new TestPanel());
}
public static void main(String[] args){
TestFrame tf = new TestFrame();
tf.setSize(500, 500);
tf.setVisible(true);
}
}
什么应该是方形JPanel:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class TestPanel extends JPanel{
private boolean isSquare;
public TestPanel(){
this.setSquare(true);
this.setLayout(new BorderLayout());
JLabel panel1 = new JLabel();
panel1.setBorder(new LineBorder(Color.RED, 4));
panel1.setBackground(Color.CYAN);
JLabel panel2 = new JLabel();
panel2.setBorder(new LineBorder(Color.BLUE, 4));
panel2.setBackground(Color.CYAN);
this.setBorder(new LineBorder(Color.GREEN, 4));
this.setBackground(Color.CYAN);
this.add(panel1, BorderLayout.WEST);
this.add(panel2, BorderLayout.EAST);
}
public void paint(Graphics g){
if(this.isSquare()){
Dimension d = this.getSize();
if(d.height > d.width){
this.setSize(d.width, d.width);
} else {
this.setSize(d.height, d.height);
}
super.paint(g);
}
}
private boolean isSquare() {
return isSquare;
}
private void setSquare(boolean isSquare) {
this.isSquare = isSquare;
}
}
答案 0 :(得分:8)
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class SoSquare {
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
// the GUI as seen by the user (without frame)
// A single component added to a GBL with no constraint
// will be centered.
JPanel gui = new JPanel(new GridBagLayout());
gui.setBackground(Color.WHITE);
SquarePanel p = new SquarePanel();
p.setBackground(Color.red);
gui.add(p);
JFrame f = new JFrame("Demo");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
f.setSize(400,100);
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
/**
* A square panel for rendering. NOTE: To work correctly, this must be the only
* component in a parent with a layout that allows the child to decide the size.
*/
class SquarePanel extends JPanel {
@Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
Container c = getParent();
if (c != null) {
d = c.getSize();
} else {
return new Dimension(10, 10);
}
int w = (int) d.getWidth();
int h = (int) d.getHeight();
int s = (w < h ? w : h);
return new Dimension(s, s);
}
}
答案 1 :(得分:4)
利用符合组件首选/最小/最大大小的布局管理器。覆盖getPreferred/Minimum/MaximumSize
方法以返回所需的大小。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class SqaurePaneTest {
public static void main(String[] args) {
new SqaurePaneTest();
}
public SqaurePaneTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
add(new JLabel("Look ma, I'm a square", JLabel.CENTER));
setBorder(new LineBorder(Color.GRAY));
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
@Override
public Dimension getMaximumSize() {
return getPreferredSize();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
或者,创建自己的布局管理器,执行相同的操作(使所有组件成为正方形)