package app; // Java imports import java.awt.*; import java.util.*; import javax.swing.*; // Project imports import vue.*; // List of CPU registers class RegisterList extends JScrollPane { // Package fields CPUWindow parent; // Containing CPU window // Private fields private boolean shown; // Component has been shown private HashMap registers; // Register items // UI components private JPanel client; // Client area /////////////////////////////////////////////////////////////////////////// // Constructors // /////////////////////////////////////////////////////////////////////////// // Default constructor RegisterList(CPUWindow parent, boolean system) { super(VERTICAL_SCROLLBAR_ALWAYS, HORIZONTAL_SCROLLBAR_AS_NEEDED); // Configure instance fields this.parent = parent; registers = new HashMap(); shown = true; // Configure client area client = new JPanel(new GridBagLayout()) { public Dimension getPreferredSize() { var ret = super.getPreferredSize(); if (!shown) ret.height = system ? getInitialHeight() : 0; return ret; } public void paintComponent(Graphics g) { shown = true; super.paintComponent(g); } }; client.setBackground(SystemColor.window); client.setFocusable(true); // Initialize system registers if (system) { new Register(this, "PC" , VUE.PC , VUE.PC ); new Register(this, "PSW" , VUE.PSW , VUE.PSW ); new Register(this, "EIPC" , VUE.EIPC , Register.PLAIN); new Register(this, "EIPSW", VUE.EIPSW, VUE.PSW ); new Register(this, "FEPC" , VUE.FEPC , Register.PLAIN); new Register(this, "FEPSW", VUE.FEPSW, VUE.PSW ); new Register(this, "ECR" , VUE.ECR , VUE.ECR ); new Register(this, "ADTRE", VUE.ADTRE, Register.PLAIN); new Register(this, "CHCW" , VUE.CHCW , VUE.CHCW ); new Register(this, "PIR" , VUE.PIR , VUE.PIR ); new Register(this, "TKCW" , VUE.TKCW , VUE.TKCW ); new Register(this, "29" , 29, Register.PLAIN); new Register(this, "30" , 30, Register.PLAIN); new Register(this, "31" , 31, Register.PLAIN); } // Initialize program registers else for (int x = 0; x < 32; x++) { String name = null; switch (x) { case VUE.GP: name = "gp"; break; case VUE.HP: name = "hp"; break; case VUE.LP: name = "lp"; break; case VUE.SP: name = "sp"; break; case VUE.TP: name = "tp"; break; } new Register(this, name, x, Register.PROGRAM); } // List terminator var spacer = new JPanel(null); spacer.setOpaque(false); spacer.setPreferredSize(new Dimension(0, 0)); var gbc = new GridBagConstraints(); gbc.gridheight = GridBagConstraints.REMAINDER; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.weighty = 1; client.add(spacer, gbc); // Configure component shown = false; setViewportView(client); } /////////////////////////////////////////////////////////////////////////// // Public Methods // /////////////////////////////////////////////////////////////////////////// // Draw the component public void paintComponent(Graphics g) { if (!shown) { shown = true; revalidate(); } super.paintComponent(g); } // Transfer focus to the client area public void requestFocus() { client.requestFocus(); } // Recalculate layout public void revalidate() { if (client != null) client.revalidate(); super.revalidate(); repaint(); } /////////////////////////////////////////////////////////////////////////// // Package Methods // /////////////////////////////////////////////////////////////////////////// // Add a register component to the client area void add(GridBagConstraints gbc, JComponent comp) { client.add(comp, gbc); } // Associate a register with its index void add(int index, Register register) { registers.put(index, register); } // Apply configuration settings void configure() { // Configure registers for (var reg : registers.values()) reg.configure(); // Configure component getVerticalScrollBar().setUnitIncrement( CPUWindow.regHexFontSize.height); } // Update the display void refresh() { for (var reg : registers.values()) reg.refresh(); } /////////////////////////////////////////////////////////////////////////// // Private Methods // /////////////////////////////////////////////////////////////////////////// // Determine the initial height upon first show private int getInitialHeight() { int height = 0; var layout = (GridBagLayout) client.getLayout(); int ret = 0; int row = 0; // Process controls until the target row is found for (var control : client.getComponents()) { var ctrl = (JComponent) control; // Track the tallest control on the row if (ctrl.isVisible()) height = Math.max(height, ctrl.getPreferredSize().height); // This is not the last control on the row if (layout.getConstraints(control).gridwidth != GridBagConstraints.REMAINDER) continue; // Advance to the next row ret += height; height = 0; row++; // The target row has been reached if (row == 4) break; } return ret; } }