java - 从事 Java GUI/Canvas 项目

标签 java swing user-interface canvas

嗨,我是 Java 中的 GUI 和 Canvas 新手。我正在开发一个项目,我需要一个 GUI/Canvas(仍然对差异感到困惑),我猜它有三个框架。基本上,它是一个电梯项目,在 Canvas 的两侧都有一个矩形电梯对象,中间是用于表示楼层的按钮(彼此堆叠)(因此,如果单击该按钮,电梯移动到与按钮相同的行)。我不知道你将如何为此设计 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);
}

最佳答案

这是一个有内涵的问题。

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

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

基本上,您想要分离职责范围。

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

电梯模型控制单个井道的电梯所在位置,就像建筑模型控制诸如楼层数、单个电梯模型、确定如何将电梯调用到楼层的算法等内容一样......

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

enter image description here

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

        }

    }

}

关于java - 从事 Java GUI/Canvas 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13022853/

相关文章:

java - 无法更改 GridLayout 中 JLabel 的大小

java - 为什么有人要这样做?

java - 为什么你会捕获 Throwable 而除了打印堆栈跟踪之外什么都不做?

java - Netbeans 新项目向导不显示 Maven Web 应用程序

具有观察者模式的 Java MVC 不同步不同 View

java - Java 中的 GUI 控制流和回调

c++ - 以编程方式确保随机调色板充满活力并且与背景截然不同

java - 如何以人类可读的方式在 Java 中显示日历?

Java:文件菜单点击是否获得焦点?

java - 动态定制基因jFrame