pvbemu/src/desktop/app/RegisterList.java

202 lines
6.3 KiB
Java

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<Integer, Register> 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<Integer, Register>();
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;
}
}