Java 我如何复制一个JPanel,它的所有jcomponents都具有与原始面板相同的功能?
这是一个gui转换项目。我有一个jcombobox,在选择相应的jbutton时,它会更新我的jpanel jpTransDetails,执行平移、旋转等操作。现在,我必须处理另一个部分,我希望得到这个jcomboBox和JPanel转换细节的精确副本,这些细节具有与此相同的功能。实现这一目标的最佳方式是什么 请注意,我只向您展示了部分代码,以避免冗长。对其他变换重复这些部分 更新:我尝试过创建一个基本示例,使用类将新的jpanel添加到jpanel中,但它不起作用Java 我如何复制一个JPanel,它的所有jcomponents都具有与原始面板相同的功能?,java,swing,user-interface,Java,Swing,User Interface,这是一个gui转换项目。我有一个jcombobox,在选择相应的jbutton时,它会更新我的jpanel jpTransDetails,执行平移、旋转等操作。现在,我必须处理另一个部分,我希望得到这个jcomboBox和JPanel转换细节的精确副本,这些细节具有与此相同的功能。实现这一目标的最佳方式是什么 请注意,我只向您展示了部分代码,以避免冗长。对其他变换重复这些部分 更新:我尝试过创建一个基本示例,使用类将新的jpanel添加到jpanel中,但它不起作用 transNameLi
transNameList = new String[] {"Translation","Rotation","Scaling","Shear","Reflection"};
jcbTranslations = new JComboBox(transNameList);
mPane.add(jcbTranslations); //mPane is my main jpanel
//transDetails JPANEL
jpTransDetails = new JPanel(null);
jpTransDetails.setBounds(10,95,320,103);
jpTransDetails.setOpaque(false);
Border border = BorderFactory.createLineBorder(Color.white);
jpTransDetails.setBorder(border);
//TRANSLATION
JLabel lblTx = new JLabel("Enter X-Coordinate: ");
lblTx.setForeground(Color.BLACK);
lblTx.setFont(new Font("Segoe UI", Font.PLAIN, 12));
lblTx.setBounds(10,6,150,12);
lblTx.setToolTipText("Number of units moved along x-axis");
tTx = new JTextField();
tTx.setText("0");
tTx.setColumns(10);
tTx.setBounds(175, 4, 50, 18);
JLabel lblTy = new JLabel("Enter Y-Coordinate: ");
lblTy.setForeground(Color.black);
lblTy.setFont(new Font("Segoe UI", Font.PLAIN, 12));
lblTy.setBounds(10, 60, 150, 12);
lblTy.setToolTipText("Number of units moved along y-axis");
tTy = new JTextField();
tTy.setText("0");
tTy.setColumns(10);
tTy.setBounds(175, 60, 50, 18);
bTranslate = new JButton("TRANSLATE");
bTranslate.setBounds(210,1,110, 25);
bTranslate.setBackground(Color.black);
bTranslate.setForeground(Color.WHITE);
//JPANEL FOR TRANSFORMATION BUTTON
jpTransBtn =new JPanel(null);
jpTransBtn.setBounds(10,200,320,28);
jpTransBtn.setOpaque(false);
jpTransDetails.setBounds(10,95,320,100);
//ADDING FOR TRANSLATION
jpTransDetails.add(lblTx);
jpTransDetails.add(tTx);
jpTransDetails.add(lblTy);
jpTransDetails.add(tTy);
//ADDING TRANSLATION BUTTON
jpTransBtn.add(bTranslate);
mPane.add(jpTransDetails);
mPane.add(jpTransBtn);
//ITEM LISTENER FOR jcbTranslations
jcbTranslations.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent event)
{
if (event.getStateChange() == ItemEvent.SELECTED)
{
if (jcbTranslations.getSelectedIndex()==0) //TRANSLATION
{
jpTransDetails.removeAll();
jpTransDetails.repaint();
jpTransBtn.removeAll();
jpTransBtn.repaint();
//ADDING FOR TRANSLATION
jpTransDetails.add(lblTx);
jpTransDetails.add(tTx);
jpTransDetails.add(lblTy);
jpTransDetails.add(tTy);
//ADDING TRANSLATION BUTTON
jpTransBtn.add(bTranslate);
}
if (jcbTranslations.getSelectedIndex()==1) //ROTATION
{
jpTransDetails.removeAll();
jpTransDetails.repaint();
jpTransBtn.removeAll();
jpTransBtn.repaint();
//ADDING FOR ROTATION
jpTransDetails.add(lblRx);
jpTransDetails.add(Rotx);
jpTransDetails.add(lblRy);
jpTransDetails.add(Roty);
jpTransDetails.add(lblAngx);
jpTransDetails.add(tAngle);
//ADDING ROTATION BUTTON
jpTransBtn.add(bRotate);
}
更新
public class MainPanelClass extends JFrame
{
public static JPanel selectionpanel;
MainPanelClass()
{
selectionpanel = new JPanel();
selectionpanel.setPreferredSize(new Dimension(100,200));
selectionpanel.setBackground(Color.BLUE);
selectionpanel.add(new CompositeTransformationsPanel());
add(selectionpanel);
}
public static void main(String[] args)
{
MainPanelClass mpc = new MainPanelClass();
mpc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mpc.setVisible(true);
mpc.setSize(300,400);
}
}
最好的方法是创建一个类,该类通过组合扩展JPanel或包含JPanel,其工作是每次都以完全相同的方式创建感兴趣的组件。如果您需要两者共享模型,那么您可以给这个类一个复制构造函数,它从所有组件中提取模型,并将这些相同的模型放在新创建的JPanel中 其他建议: 避免空布局和设置框,因为这会导致无法适应不同操作系统或使用的僵化GUI。更好地学习和使用布局管理器。 尽量将模型代码(程序的非GUI逻辑部分)与视图(GUI部分)分开。这将使实现这类事情变得更容易,并且使调试和测试代码变得更容易。 与手动卸下和更换组件相比,使用可更轻松、更安全地交换组件的 在审阅您的代码时,我的建议已更改。看起来您希望创建用于对点执行转换的输入表单,并且希望根据JComboBox中的选择更改转换的类型。如果是,我的建议是: 可能不需要创建多个类似的JPanel和交换JPanel 取而代之的是使用一个JPanel来完成整个任务 给它一个按钮,比如说提交 给那个JButton一个ActionListner 在该侦听器中,检查JComboBox的当前状态,即所选项 根据所选项目进行适当的计算。 例如:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.Border;
@SuppressWarnings("serial")
public class PointManipulationPanel extends JPanel {
private static final int GAP = 5;
private JComboBox<Transform> transformCombo = new JComboBox<Transform>(Transform.values());
private JTextField xCoordField = new JTextField("0", 5);
private JTextField yCoordField = new JTextField("0", 5);
public PointManipulationPanel() {
JPanel coordinatePanel = new JPanel(new GridBagLayout());
Border outsideBorder = BorderFactory.createLineBorder(Color.WHITE);
Border insideBorder = BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP);
Border border = BorderFactory.createCompoundBorder(outsideBorder, insideBorder);
coordinatePanel.setBorder(border);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(GAP, GAP, GAP, GAP);
coordinatePanel.add(new JLabel("Enter X-Coordinate: "), gbc);
gbc.gridy = 1;
coordinatePanel.add(new JLabel("Enter Y-Coordinate: "), gbc);
gbc.gridx = 1;
gbc.gridy = 0;
coordinatePanel.add(xCoordField, gbc);
gbc.gridy = 1;
coordinatePanel.add(yCoordField, gbc);
JPanel topPane = new JPanel();
topPane.add(transformCombo);
JButton submitButton = new JButton("Submit");
submitButton.addActionListener(e -> submitActionPerformed(e));
JPanel bottomPanel = new JPanel();
bottomPanel.add(submitButton);
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BorderLayout(GAP, GAP));
add(topPane, BorderLayout.PAGE_START);
add(coordinatePanel);
add(bottomPanel, BorderLayout.PAGE_END);
}
private void submitActionPerformed(ActionEvent e) {
int x = 0;
int y = 0;
try {
x = Integer.parseInt(xCoordField.getText());
y = Integer.parseInt(yCoordField.getText());
} catch (NumberFormatException nfe) {
// warn user with JOptionPane that data entered no goo
String message = "Invalid number entry";
String title = "Invalid Data";
int messageType = JOptionPane.ERROR_MESSAGE;
JOptionPane.showMessageDialog(PointManipulationPanel.this, message, title, messageType);
// exit method
return;
}
// use x and y here in the calculations
Transform transform = (Transform) transformCombo.getSelectedItem();
switch (transform) {
case TRANSLATION:
// TODO: real code to do calculations goes here
System.out.printf("Do translation here on x and y: [%d, %d]%n", x, y);
break;
case ROTATION:
// TODO: real code to do calculations goes here
System.out.printf("Do rotation here on x and y: [%d, %d]%n", x, y);
break;
case SCALING:
// TODO: real code to do calculations goes here
System.out.printf("Do scaling here on x and y: [%d, %d]%n", x, y);
break;
case SHEAR:
// TODO: real code to do calculations goes here
System.out.printf("Do shear here on x and y: [%d, %d]%n", x, y);
break;
case REFLECTION:
// TODO: real code to do calculations goes here
System.out.printf("Do reflection here on x and y: [%d, %d]%n", x, y);
break;
default:
throw new IllegalArgumentException("Unexpected value: " + transform);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
PointManipulationPanel mainPanel = new PointManipulationPanel();
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
@Ox12345:没有人说过让类保持静态。其想法是用相同的代码和相同的方式创建感兴趣的JPanel。静态与此问题的解决方案无关。@Ox12345如果您可以创建并发布一个有效的问题代码,我可以编译、运行、调整和改进代码,那将是最好的选择。此外,图形用户界面外观的图像也有帮助。我是否需要做一些额外的事情使其可见?它没有显示出来up@Ox12345:我不知道-你知道你发布的代码对我们毫无用处,没有人可以编译、运行或测试它,也没有人可以看到你在尝试做什么。出于这个原因,我只能给出非常模糊和一般性的建议,我绝对猜不出为什么您的代码可能无法按预期工作。再次,请阅读链接,再次,请尝试创建其中一个,一个新的小程序,而不是您的整个程序,一个为我们编译、运行和说明您问题本质的程序。如果没有这个,我们所能做的就是猜测。@Ox12345:还要注意,如果您给mPane一个空布局,那么您的JComboBox可能不会出现。同样,不要使用空布局。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.Border;
@SuppressWarnings("serial")
public class PointManipulationPanel extends JPanel {
private static final int GAP = 5;
private JComboBox<Transform> transformCombo = new JComboBox<Transform>(Transform.values());
private JTextField xCoordField = new JTextField("0", 5);
private JTextField yCoordField = new JTextField("0", 5);
public PointManipulationPanel() {
JPanel coordinatePanel = new JPanel(new GridBagLayout());
Border outsideBorder = BorderFactory.createLineBorder(Color.WHITE);
Border insideBorder = BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP);
Border border = BorderFactory.createCompoundBorder(outsideBorder, insideBorder);
coordinatePanel.setBorder(border);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(GAP, GAP, GAP, GAP);
coordinatePanel.add(new JLabel("Enter X-Coordinate: "), gbc);
gbc.gridy = 1;
coordinatePanel.add(new JLabel("Enter Y-Coordinate: "), gbc);
gbc.gridx = 1;
gbc.gridy = 0;
coordinatePanel.add(xCoordField, gbc);
gbc.gridy = 1;
coordinatePanel.add(yCoordField, gbc);
JPanel topPane = new JPanel();
topPane.add(transformCombo);
JButton submitButton = new JButton("Submit");
submitButton.addActionListener(e -> submitActionPerformed(e));
JPanel bottomPanel = new JPanel();
bottomPanel.add(submitButton);
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BorderLayout(GAP, GAP));
add(topPane, BorderLayout.PAGE_START);
add(coordinatePanel);
add(bottomPanel, BorderLayout.PAGE_END);
}
private void submitActionPerformed(ActionEvent e) {
int x = 0;
int y = 0;
try {
x = Integer.parseInt(xCoordField.getText());
y = Integer.parseInt(yCoordField.getText());
} catch (NumberFormatException nfe) {
// warn user with JOptionPane that data entered no goo
String message = "Invalid number entry";
String title = "Invalid Data";
int messageType = JOptionPane.ERROR_MESSAGE;
JOptionPane.showMessageDialog(PointManipulationPanel.this, message, title, messageType);
// exit method
return;
}
// use x and y here in the calculations
Transform transform = (Transform) transformCombo.getSelectedItem();
switch (transform) {
case TRANSLATION:
// TODO: real code to do calculations goes here
System.out.printf("Do translation here on x and y: [%d, %d]%n", x, y);
break;
case ROTATION:
// TODO: real code to do calculations goes here
System.out.printf("Do rotation here on x and y: [%d, %d]%n", x, y);
break;
case SCALING:
// TODO: real code to do calculations goes here
System.out.printf("Do scaling here on x and y: [%d, %d]%n", x, y);
break;
case SHEAR:
// TODO: real code to do calculations goes here
System.out.printf("Do shear here on x and y: [%d, %d]%n", x, y);
break;
case REFLECTION:
// TODO: real code to do calculations goes here
System.out.printf("Do reflection here on x and y: [%d, %d]%n", x, y);
break;
default:
throw new IllegalArgumentException("Unexpected value: " + transform);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
PointManipulationPanel mainPanel = new PointManipulationPanel();
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
enum Transform {
TRANSLATION("Translation"), ROTATION("Rotation"), SCALING("Scaling"), SHEAR("Shear"), REFLECTION("Reflection");
private String name;
private Transform(String name) {
this.name = name;
}
String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}