0

嗨,我是 Java 中的 GUI 和 Canvas 的新手。我正在做一个项目,我需要一个我猜有三个框架的 GUI/Canvas(仍然对差异感到困惑)。基本上它是一个电梯项目,在画布的两侧都有一个矩形电梯对象,中间是用于表示楼层的按钮(彼此堆叠)(因此,如果您单击按钮,电梯移动到与按钮相同的行)。我被困在你将如何为此设计画布上。我对 gridLayout 和 broderLayouts 有一些想法,但现在都是一团糟。

谢谢

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;


public class UI extends JFrame implements ActionListener 
{
ArrayList<JButton> buttonList = new ArrayList(); 
MyCanvas mainCanvas;

public UI()
{
  super("Example Frame");
    setSize(800,600);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setVisible(true);

  mainCanvas = new MyCanvas();

  JPanel mainPanel = new JPanel();

  mainPanel.setLayout(new GridLayout(1,3));

  JPanel buttonPanel = new JPanel();
  buttonPanel.setLayout(new GridLayout(12,1));

  //while(true)
  //{
   //   myCanvas.repaint();
    //}
  for(int i=1; i<13; i++)
  {   String s = Integer.toString(i);
      buttonPanel.add(new JButton(s));
  }
  add(mainPanel);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  mainPanel.add(buttonPanel, BorderLayout.CENTER);
}
4

2 回答 2

2

这是一个加载的问题。

如果它纯粹是关于布局,那么我会使用一系列具有自己布局的复合组件来实现您需要的结果......

如果是关于方法,那么它会变得更加复杂......

基本上,您希望划分职责范围。

从问题来看,有两种不同的模型,电梯模型和建筑模型。

电梯模型控制单个竖井的电梯所在的位置,因为建筑模型控制诸如楼层数、单个电梯模型、确定电梯如何被呼叫到楼层的算法……

以下是一个想法的基本示例。它缺少(除其他外)将电梯呼叫到楼层所需的逻辑或有关电梯的状态信息(移动、等待、打开......)

在此处输入图像描述

public class Elevator {

public static void main(String[] args) {
        new Elevator();
    }

    public Elevator() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new BuildingPane());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    public enum ElevatorShaft {
        Left,
        Right
    }

    public interface ElevatorModel {
        public int getFloor();
        public void setFloor(int floor);

        public void addPropertyChangeListener(PropertyChangeListener listener);
        public void removePropertyChangeListener(PropertyChangeListener listener);
    }

    public class DefaultElevatorModel implements ElevatorModel {

        private int floor;
        private PropertyChangeSupport propertyChangeSupport;

        public DefaultElevatorModel(int floor) {
            this.floor = floor;
            propertyChangeSupport = new PropertyChangeSupport(this);
        }

        @Override
        public void addPropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.addPropertyChangeListener(listener);
        }

        @Override
        public void removePropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.removePropertyChangeListener(listener);
        }

        @Override
        public int getFloor() {
            return floor;
        }

        @Override
        public void setFloor(int value) {
            if (value != floor) {
                int old = floor;
                floor = value;
                propertyChangeSupport.firePropertyChange("floor", old, floor);
            }
        }

    }

    public interface BuildingModel {

        public int getFloorCount();
        public int getFloor(ElevatorShaft shaft);
        public ElevatorModel getElevatorModel(ElevatorShaft shaft);
        public void call(int floor);

    }

    public class DefaultBuildingModel implements BuildingModel {

        private int floorCount;

        private Map<ElevatorShaft, ElevatorModel> shaftManager;

        public DefaultBuildingModel(int floorCount) {
            this.floorCount = floorCount;
            shaftManager = new HashMap<ElevatorShaft, ElevatorModel>(2);
            shaftManager.put(ElevatorShaft.Left, new DefaultElevatorModel((int)Math.round(Math.random() * (floorCount - 1))));
            shaftManager.put(ElevatorShaft.Right, new DefaultElevatorModel((int)Math.round(Math.random() * (floorCount - 1))));
        }

        @Override
        public ElevatorModel getElevatorModel(ElevatorShaft shaft) {
            return shaftManager.get(shaft);
        }

        @Override
        public int getFloorCount() {
            return floorCount;
        }

        @Override
        public int getFloor(ElevatorShaft shaft) {
            return shaftManager.get(shaft).getFloor();
        }

        @Override
        public void call(int floor) {
            // This will need to determine which elevator should be called
            // and call that elevators model "setFloor" method...
        }

    }

    public class BuildingPane extends JPanel {

        public BuildingPane() {

            setLayout(new GridBagLayout());

            BuildingModel model = new DefaultBuildingModel(3);

            Shaft leftShaft = new Shaft(model, ElevatorShaft.Left);
            Shaft rightShaft = new Shaft(model, ElevatorShaft.Right);
            ButtonsPane buttonsPane = new ButtonsPane(model);

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.VERTICAL;

            add(leftShaft, gbc);
            gbc.gridx++;
            add(buttonsPane, gbc);
            gbc.gridx++;
            add(rightShaft, gbc);

        }

    }

    public class ButtonsPane extends JPanel {

        private BuildingModel model;

        public ButtonsPane(BuildingModel model) {

            this.model = model;

            setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weighty = 1;
            gbc.anchor = GridBagConstraints.CENTER;

            int floorCount = model.getFloorCount();
            ActionHandler handler = new ActionHandler();

            for (int floor = floorCount; floor > 0; floor--) {

                JButton button = new JButton("Floor " + floor);
                button.setActionCommand(Integer.toString(floor));
                button.addActionListener(handler);
                add(button, gbc);

                gbc.gridy++;

            }

        }

        public BuildingModel getModel() {
            return model;
        }

        public class ActionHandler implements ActionListener {

            @Override
            public void actionPerformed(ActionEvent e) {
                String cmd = e.getActionCommand();
                try {
                    int floor = Integer.parseInt(cmd);
                    getModel().call(floor);
                } catch (NumberFormatException exp) {
                    exp.printStackTrace();
                }
            }

        }

    }

    public class Shaft extends JPanel {

        private BufferedImage elevator;
        private BuildingModel buildingModel;
        private ElevatorShaft shaft;

        public Shaft(BuildingModel model, ElevatorShaft shaft) {

            this.buildingModel = model;
            this.shaft = shaft;

            buildingModel.getElevatorModel(shaft).addPropertyChangeListener(new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if (evt.getPropertyName().equalsIgnoreCase("floor")) {
                        // Need to update our position, this could
                        // be done via animation or directly call something
                        // like repaint..
                    }
                }
            });

            setBorder(new LineBorder(Color.DARK_GRAY));
            setBackground(Color.GRAY);

            try {
                elevator = ImageIO.read(new File("elevator.png"));
            } catch (IOException ex) {
                Logger.getLogger(Elevator.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

        public BuildingModel getBuildingModel() {
            return buildingModel;
        }

        public ElevatorShaft getShaft() {
            return shaft;
        }

        public int getFloorCount() {
            return getBuildingModel().getFloorCount();
        }

        public int getFloor() {
            return getBuildingModel().getFloor(getShaft());
        }

        @Override
        public Dimension getPreferredSize() {

            Dimension size = new Dimension(elevator.getWidth(), elevator.getHeight() * getFloorCount());
            Insets insets = getInsets();

            size.width += (insets.left + insets.right);
            size.height += (insets.top + insets.bottom);

            return size;

        }

        @Override
        protected void paintComponent(Graphics g) {

            super.paintComponent(g);

            Insets insets = getInsets();
            int x = insets.left;
            int y = insets.top;
            int height = getHeight() - (insets.top + insets.bottom);

            int floor = getFloor();
            y = height - (elevator.getHeight() * (floor + 1));
            g.drawImage(elevator, x, y, this);

        }

    }

}
于 2012-10-23T05:42:09.447 回答
-1

我将如何改变你的类是这样的(注意这是你需要实际实现一个动作监听器来处理按钮按下的伪代码) -

public class UI extends JFrame implements ActionListener 
{
ArrayList<JButton> buttonList = new ArrayList(); 

int x = 0;
int y = 0;
int width = 50;
int height = 50;

public UI()
{
  super("Example Frame");
  setSize(800,600);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setVisible(true);    

  JPanel mainPanel = new JPanel();

  mainPanel.setLayout(new GridLayout(1,3));

  JPanel buttonPanel = new JPanel();
  buttonPanel.setLayout(new GridLayout(12,1));

  for(int i=1; i<13; i++)
  {   String s = Integer.toString(i);
      buttonPanel.add(new JButton(s));
  }

  add(mainPanel);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  mainPanel.add(buttonPanel, BorderLayout.CENTER);
}

public void paint(Graphics g){
    super.paint(g);
    g.drawRect(x,y,width,height);
}

onButtonPress(int buttonNumber){
    y = buttonNumber * 10;
    repaint();
}
于 2012-10-23T03:20:10.077 回答