package app; // Java imports import java.awt.*; import java.util.*; import javax.swing.*; // Project imports import util.*; import vue.*; // List of CPU registers class RegisterList extends JScrollPane { // Package fields CPUWindow parent; // Containing CPU window HashMap registers; // Register items // Private fields private boolean shown; // Component has been shown // UI components private UPanel 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 UPanel(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.addMouseListener(Util.onMouse(e->client.requestFocus(), null)); 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 UPanel(); 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 configure2() { // Configure registers for (var reg : registers.values()) reg.configure(); // Configure component getVerticalScrollBar().setUnitIncrement( parent.parent.app.fntMono.metrics.getHeight()); } // 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; } }