204 lines
6.3 KiB
Java
204 lines
6.3 KiB
Java
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<Integer, Register> registers; // Register items
|
|
|
|
// Private fields
|
|
private boolean shown; // Component has been shown
|
|
|
|
// 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.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 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;
|
|
}
|
|
|
|
}
|