Spaces:
Sleeping
Sleeping
| /* | |
| * PuzzleApplet.java: NestedVM applet for the puzzle collection | |
| */ | |
| import java.awt.*; | |
| import java.awt.event.*; | |
| import java.awt.image.BufferedImage; | |
| import java.util.*; | |
| import javax.swing.*; | |
| import javax.swing.border.BevelBorder; | |
| import javax.swing.Timer; | |
| import java.util.List; | |
| import org.ibex.nestedvm.Runtime; | |
| public class PuzzleApplet extends JApplet implements Runtime.CallJavaCB { | |
| private static final long serialVersionUID = 1L; | |
| private static final int CFG_SETTINGS = 0, CFG_SEED = 1, CFG_DESC = 2, | |
| LEFT_BUTTON = 0x0200, MIDDLE_BUTTON = 0x201, RIGHT_BUTTON = 0x202, | |
| LEFT_DRAG = 0x203, MIDDLE_DRAG = 0x204, RIGHT_DRAG = 0x205, | |
| LEFT_RELEASE = 0x206, CURSOR_UP = 0x209, CURSOR_DOWN = 0x20a, | |
| CURSOR_LEFT = 0x20b, CURSOR_RIGHT = 0x20c, MOD_CTRL = 0x1000, | |
| MOD_SHFT = 0x2000, MOD_NUM_KEYPAD = 0x4000, ALIGN_VCENTRE = 0x100, | |
| ALIGN_HCENTRE = 0x001, ALIGN_HRIGHT = 0x002, C_STRING = 0, | |
| C_CHOICES = 1, C_BOOLEAN = 2; | |
| private JFrame mainWindow; | |
| private JMenu typeMenu; | |
| private JMenuItem[] typeMenuItems; | |
| private int customMenuItemIndex; | |
| private JMenuItem solveCommand; | |
| private Color[] colors; | |
| private JLabel statusBar; | |
| private PuzzlePanel pp; | |
| private Runtime runtime; | |
| private String[] puzzle_args; | |
| private Graphics2D gg; | |
| private Timer timer; | |
| private int xarg1, xarg2, xarg3; | |
| private int[] xPoints, yPoints; | |
| private BufferedImage[] blitters = new BufferedImage[512]; | |
| private ConfigDialog dlg; | |
| static { | |
| try { | |
| UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); | |
| } catch (Exception ex) { | |
| ex.printStackTrace(); | |
| } | |
| } | |
| public void init() { | |
| try { | |
| Container cp = getContentPane(); | |
| cp.setLayout(new BorderLayout()); | |
| runtime = (Runtime) Class.forName("PuzzleEngine").newInstance(); | |
| runtime.setCallJavaCB(this); | |
| JMenuBar menubar = new JMenuBar(); | |
| JMenu jm; | |
| menubar.add(jm = new JMenu("Game")); | |
| addMenuItemCallback(jm, "New", "jcallback_newgame_event"); | |
| addMenuItemCallback(jm, "Restart", "jcallback_restart_event"); | |
| addMenuItemCallback(jm, "Specific...", "jcallback_config_event", CFG_DESC); | |
| addMenuItemCallback(jm, "Random Seed...", "jcallback_config_event", CFG_SEED); | |
| jm.addSeparator(); | |
| addMenuItemCallback(jm, "Undo", "jcallback_undo_event"); | |
| addMenuItemCallback(jm, "Redo", "jcallback_redo_event"); | |
| jm.addSeparator(); | |
| solveCommand = addMenuItemCallback(jm, "Solve", "jcallback_solve_event"); | |
| solveCommand.setEnabled(false); | |
| if (mainWindow != null) { | |
| jm.addSeparator(); | |
| addMenuItemCallback(jm, "Exit", "jcallback_quit_event"); | |
| } | |
| menubar.add(typeMenu = new JMenu("Type")); | |
| typeMenu.setVisible(false); | |
| menubar.add(jm = new JMenu("Help")); | |
| addMenuItemCallback(jm, "About", "jcallback_about_event"); | |
| setJMenuBar(menubar); | |
| cp.add(pp = new PuzzlePanel(), BorderLayout.CENTER); | |
| pp.addKeyListener(new KeyAdapter() { | |
| public void keyPressed(KeyEvent e) { | |
| int key = -1; | |
| int shift = e.isShiftDown() ? MOD_SHFT : 0; | |
| int ctrl = e.isControlDown() ? MOD_CTRL : 0; | |
| switch (e.getKeyCode()) { | |
| case KeyEvent.VK_LEFT: | |
| case KeyEvent.VK_KP_LEFT: | |
| key = shift | ctrl | CURSOR_LEFT; | |
| break; | |
| case KeyEvent.VK_RIGHT: | |
| case KeyEvent.VK_KP_RIGHT: | |
| key = shift | ctrl | CURSOR_RIGHT; | |
| break; | |
| case KeyEvent.VK_UP: | |
| case KeyEvent.VK_KP_UP: | |
| key = shift | ctrl | CURSOR_UP; | |
| break; | |
| case KeyEvent.VK_DOWN: | |
| case KeyEvent.VK_KP_DOWN: | |
| key = shift | ctrl | CURSOR_DOWN; | |
| break; | |
| case KeyEvent.VK_PAGE_UP: | |
| key = shift | ctrl | MOD_NUM_KEYPAD | '9'; | |
| break; | |
| case KeyEvent.VK_PAGE_DOWN: | |
| key = shift | ctrl | MOD_NUM_KEYPAD | '3'; | |
| break; | |
| case KeyEvent.VK_HOME: | |
| key = shift | ctrl | MOD_NUM_KEYPAD | '7'; | |
| break; | |
| case KeyEvent.VK_END: | |
| key = shift | ctrl | MOD_NUM_KEYPAD | '1'; | |
| break; | |
| default: | |
| if (e.getKeyCode() >= KeyEvent.VK_NUMPAD0 && e.getKeyCode() <=KeyEvent.VK_NUMPAD9) { | |
| key = MOD_NUM_KEYPAD | (e.getKeyCode() - KeyEvent.VK_NUMPAD0+'0'); | |
| } | |
| break; | |
| } | |
| if (key != -1) { | |
| runtimeCall("jcallback_key_event", new int[] {0, 0, key}); | |
| } | |
| } | |
| public void keyTyped(KeyEvent e) { | |
| int key = e.getKeyChar(); | |
| if (key == 26 && e.isShiftDown() && e.isControlDown()) { | |
| runtimeCall("jcallback_redo_event", new int[0]); | |
| return; | |
| } | |
| runtimeCall("jcallback_key_event", new int[] {0, 0, key}); | |
| } | |
| }); | |
| pp.addMouseListener(new MouseAdapter() { | |
| public void mouseReleased(MouseEvent e) { | |
| mousePressedReleased(e, true); | |
| } | |
| public void mousePressed(MouseEvent e) { | |
| pp.requestFocus(); | |
| mousePressedReleased(e, false); | |
| } | |
| private void mousePressedReleased(MouseEvent e, boolean released) { | |
| int button; | |
| if ((e.getModifiers() & (InputEvent.BUTTON2_MASK | InputEvent.SHIFT_MASK)) != 0) | |
| button = MIDDLE_BUTTON; | |
| else if ((e.getModifiers() & (InputEvent.BUTTON3_MASK | InputEvent.ALT_MASK)) != 0) | |
| button = RIGHT_BUTTON; | |
| else if ((e.getModifiers() & (InputEvent.BUTTON1_MASK)) != 0) | |
| button = LEFT_BUTTON; | |
| else | |
| return; | |
| if (released) | |
| button += LEFT_RELEASE - LEFT_BUTTON; | |
| runtimeCall("jcallback_key_event", new int[] {e.getX(), e.getY(), button}); | |
| } | |
| }); | |
| pp.addMouseMotionListener(new MouseMotionAdapter() { | |
| public void mouseDragged(MouseEvent e) { | |
| int button; | |
| if ((e.getModifiers() & (InputEvent.BUTTON2_MASK | InputEvent.SHIFT_MASK)) != 0) | |
| button = MIDDLE_DRAG; | |
| else if ((e.getModifiers() & (InputEvent.BUTTON3_MASK | InputEvent.ALT_MASK)) != 0) | |
| button = RIGHT_DRAG; | |
| else | |
| button = LEFT_DRAG; | |
| runtimeCall("jcallback_key_event", new int[] {e.getX(), e.getY(), button}); | |
| } | |
| }); | |
| pp.addComponentListener(new ComponentAdapter() { | |
| public void componentResized(ComponentEvent e) { | |
| handleResized(); | |
| } | |
| }); | |
| pp.setFocusable(true); | |
| pp.requestFocus(); | |
| timer = new Timer(20, new ActionListener() { | |
| public void actionPerformed(ActionEvent e) { | |
| runtimeCall("jcallback_timer_func", new int[0]); | |
| } | |
| }); | |
| String gameid; | |
| try { | |
| gameid = getParameter("game_id"); | |
| } catch (java.lang.NullPointerException ex) { | |
| gameid = null; | |
| } | |
| if (gameid == null) { | |
| puzzle_args = null; | |
| } else { | |
| puzzle_args = new String[2]; | |
| puzzle_args[0] = "puzzle"; | |
| puzzle_args[1] = gameid; | |
| } | |
| SwingUtilities.invokeLater(new Runnable() { | |
| public void run() { | |
| runtime.start(puzzle_args); | |
| runtime.execute(); | |
| } | |
| }); | |
| } catch (Exception ex) { | |
| ex.printStackTrace(); | |
| } | |
| } | |
| public void destroy() { | |
| SwingUtilities.invokeLater(new Runnable() { | |
| public void run() { | |
| runtime.execute(); | |
| if (mainWindow != null) { | |
| mainWindow.dispose(); | |
| System.exit(0); | |
| } | |
| } | |
| }); | |
| } | |
| protected void handleResized() { | |
| pp.createBackBuffer(pp.getWidth(), pp.getHeight(), colors[0]); | |
| runtimeCall("jcallback_resize", new int[] {pp.getWidth(), pp.getHeight()}); | |
| } | |
| private JMenuItem addMenuItemCallback(JMenu jm, String name, final String callback, final int arg) { | |
| return addMenuItemCallback(jm, name, callback, new int[] {arg}, false); | |
| } | |
| private JMenuItem addMenuItemCallback(JMenu jm, String name, final String callback) { | |
| return addMenuItemCallback(jm, name, callback, new int[0], false); | |
| } | |
| private JMenuItem addMenuItemCallback(JMenu jm, String name, final String callback, final int[] args, boolean checkbox) { | |
| JMenuItem jmi; | |
| if (checkbox) | |
| jm.add(jmi = new JCheckBoxMenuItem(name)); | |
| else | |
| jm.add(jmi = new JMenuItem(name)); | |
| jmi.addActionListener(new ActionListener() { | |
| public void actionPerformed(ActionEvent e) { | |
| runtimeCall(callback, args); | |
| } | |
| }); | |
| return jmi; | |
| } | |
| protected void runtimeCall(String func, int[] args) { | |
| if (runtimeCallWithResult(func, args) == 42 && mainWindow != null) { | |
| destroy(); | |
| } | |
| } | |
| protected int runtimeCallWithResult(String func, int[] args) { | |
| try { | |
| return runtime.call(func, args); | |
| } catch (Runtime.CallException ex) { | |
| ex.printStackTrace(); | |
| return 42; | |
| } | |
| } | |
| private void buildConfigureMenuItem() { | |
| if (typeMenu.isVisible()) { | |
| typeMenu.addSeparator(); | |
| } else { | |
| typeMenu.setVisible(true); | |
| } | |
| typeMenuItems[customMenuItemIndex] = | |
| addMenuItemCallback(typeMenu, "Custom...", | |
| "jcallback_config_event", | |
| new int[] {CFG_SETTINGS}, true); | |
| } | |
| private void addTypeItem | |
| (JMenu targetMenu, String name, int newId, final int ptrGameParams) { | |
| typeMenu.setVisible(true); | |
| typeMenuItems[newId] = | |
| addMenuItemCallback(targetMenu, name, | |
| "jcallback_preset_event", | |
| new int[] {ptrGameParams}, true); | |
| } | |
| private void addTypeSubmenu | |
| (JMenu targetMenu, String name, int newId) { | |
| JMenu newMenu = new JMenu(name); | |
| newMenu.setVisible(true); | |
| typeMenuItems[newId] = newMenu; | |
| targetMenu.add(newMenu); | |
| } | |
| public int call(int cmd, int arg1, int arg2, int arg3) { | |
| try { | |
| switch(cmd) { | |
| case 0: // initialize | |
| if (mainWindow != null) mainWindow.setTitle(runtime.cstring(arg1)); | |
| if ((arg2 & 1) != 0) buildConfigureMenuItem(); | |
| if ((arg2 & 2) != 0) addStatusBar(); | |
| if ((arg2 & 4) != 0) solveCommand.setEnabled(true); | |
| colors = new Color[arg3]; | |
| return 0; | |
| case 1: // configure Type menu | |
| if (arg1 == 0) { | |
| // preliminary setup | |
| typeMenuItems = new JMenuItem[arg2 + 2]; | |
| typeMenuItems[arg2] = typeMenu; | |
| customMenuItemIndex = arg2 + 1; | |
| return arg2; | |
| } else if (xarg1 != 0) { | |
| addTypeItem((JMenu)typeMenuItems[arg2], | |
| runtime.cstring(arg1), arg3, xarg1); | |
| } else { | |
| addTypeSubmenu((JMenu)typeMenuItems[arg2], | |
| runtime.cstring(arg1), arg3); | |
| } | |
| return 0; | |
| case 2: // MessageBox | |
| JOptionPane.showMessageDialog(this, runtime.cstring(arg2), runtime.cstring(arg1), arg3 == 0 ? JOptionPane.INFORMATION_MESSAGE : JOptionPane.ERROR_MESSAGE); | |
| return 0; | |
| case 3: // Resize | |
| pp.setPreferredSize(new Dimension(arg1, arg2)); | |
| if (mainWindow != null) mainWindow.pack(); | |
| handleResized(); | |
| if (mainWindow != null) mainWindow.setVisible(true); | |
| return 0; | |
| case 4: // drawing tasks | |
| switch(arg1) { | |
| case 0: | |
| String text = runtime.cstring(arg2); | |
| if (text.equals("")) text = " "; | |
| statusBar.setText(text); | |
| break; | |
| case 1: | |
| gg = pp.backBuffer.createGraphics(); | |
| if (arg2 != 0 || arg3 != 0 || | |
| arg2 + xarg2 != getWidth() || | |
| arg3 + xarg3 != getHeight()) { | |
| int left = arg2, right = arg2 + xarg2; | |
| int top = arg3, bottom = arg3 + xarg3; | |
| int width = getWidth(), height = getHeight(); | |
| gg.setColor(colors != null ? colors[0] : Color.black); | |
| gg.fillRect(0, 0, left, height); | |
| gg.fillRect(right, 0, width-right, height); | |
| gg.fillRect(0, 0, width, top); | |
| gg.fillRect(0, bottom, width, height-bottom); | |
| gg.setClip(left, top, right-left, bottom-top); | |
| } | |
| break; | |
| case 2: gg.dispose(); pp.repaint(); break; | |
| case 3: gg.setClip(arg2, arg3, xarg1, xarg2); break; | |
| case 4: | |
| if (arg2 == 0 && arg3 == 0) { | |
| gg.setClip(0, 0, getWidth(), getHeight()); | |
| } else { | |
| gg.setClip(arg2, arg3, getWidth()-2*arg2, getHeight()-2*arg3); | |
| } | |
| break; | |
| case 5: | |
| gg.setColor(colors[xarg3]); | |
| gg.fillRect(arg2, arg3, xarg1, xarg2); | |
| break; | |
| case 6: | |
| gg.setColor(colors[xarg3]); | |
| gg.drawLine(arg2, arg3, xarg1, xarg2); | |
| break; | |
| case 7: | |
| xPoints = new int[arg2]; | |
| yPoints = new int[arg2]; | |
| break; | |
| case 8: | |
| if (arg3 != -1) { | |
| gg.setColor(colors[arg3]); | |
| gg.fillPolygon(xPoints, yPoints, xPoints.length); | |
| } | |
| gg.setColor(colors[arg2]); | |
| gg.drawPolygon(xPoints, yPoints, xPoints.length); | |
| break; | |
| case 9: | |
| if (arg3 != -1) { | |
| gg.setColor(colors[arg3]); | |
| gg.fillOval(xarg1-xarg3, xarg2-xarg3, xarg3*2, xarg3*2); | |
| } | |
| gg.setColor(colors[arg2]); | |
| gg.drawOval(xarg1-xarg3, xarg2-xarg3, xarg3*2, xarg3*2); | |
| break; | |
| case 10: | |
| for(int i=0; i<blitters.length; i++) { | |
| if (blitters[i] == null) { | |
| blitters[i] = new BufferedImage(arg2, arg3, BufferedImage.TYPE_3BYTE_BGR); | |
| return i; | |
| } | |
| } | |
| throw new RuntimeException("No free blitter found!"); | |
| case 11: blitters[arg2] = null; break; | |
| case 12: | |
| timer.start(); break; | |
| case 13: | |
| timer.stop(); break; | |
| } | |
| return 0; | |
| case 5: // more arguments | |
| xarg1 = arg1; | |
| xarg2 = arg2; | |
| xarg3 = arg3; | |
| return 0; | |
| case 6: // polygon vertex | |
| xPoints[arg1]=arg2; | |
| yPoints[arg1]=arg3; | |
| return 0; | |
| case 7: // string | |
| gg.setColor(colors[arg2]); | |
| { | |
| String text = runtime.utfstring(arg3); | |
| Font ft = new Font((xarg3 & 0x10) != 0 ? "Monospaced" : "Dialog", | |
| Font.PLAIN, 100); | |
| int height100 = this.getFontMetrics(ft).getHeight(); | |
| ft = ft.deriveFont(arg1 * 100 / (float)height100); | |
| FontMetrics fm = this.getFontMetrics(ft); | |
| int asc = fm.getAscent(), desc = fm.getDescent(); | |
| if ((xarg3 & ALIGN_VCENTRE) != 0) | |
| xarg2 += asc - (asc+desc)/2; | |
| int wid = fm.stringWidth(text); | |
| if ((xarg3 & ALIGN_HCENTRE) != 0) | |
| xarg1 -= wid / 2; | |
| else if ((xarg3 & ALIGN_HRIGHT) != 0) | |
| xarg1 -= wid; | |
| gg.setFont(ft); | |
| gg.drawString(text, xarg1, xarg2); | |
| } | |
| return 0; | |
| case 8: // blitter_save | |
| Graphics g2 = blitters[arg1].createGraphics(); | |
| g2.drawImage(pp.backBuffer, 0, 0, blitters[arg1].getWidth(), blitters[arg1].getHeight(), | |
| arg2, arg3, arg2 + blitters[arg1].getWidth(), arg3 + blitters[arg1].getHeight(), this); | |
| g2.dispose(); | |
| return 0; | |
| case 9: // blitter_load | |
| gg.drawImage(blitters[arg1], arg2, arg3, this); | |
| return 0; | |
| case 10: // dialog_init | |
| dlg= new ConfigDialog(this, runtime.cstring(arg1)); | |
| return 0; | |
| case 11: // dialog_add_control | |
| { | |
| int sval_ptr = arg1; | |
| int ival = arg2; | |
| int ptr = xarg1; | |
| int type=xarg2; | |
| String name = runtime.cstring(xarg3); | |
| switch(type) { | |
| case C_STRING: | |
| dlg.addTextBox(ptr, name, runtime.cstring(sval_ptr)); | |
| break; | |
| case C_BOOLEAN: | |
| dlg.addCheckBox(ptr, name, ival != 0); | |
| break; | |
| case C_CHOICES: | |
| dlg.addComboBox(ptr, name, runtime.cstring(sval_ptr), ival); | |
| } | |
| } | |
| return 0; | |
| case 12: | |
| dlg.finish(); | |
| dlg = null; | |
| return 0; | |
| case 13: // tick a menu item | |
| if (arg1 < 0) arg1 = customMenuItemIndex; | |
| for (int i = 0; i < typeMenuItems.length; i++) { | |
| if (typeMenuItems[i] instanceof JCheckBoxMenuItem) { | |
| ((JCheckBoxMenuItem)typeMenuItems[i]).setSelected | |
| (arg1 == i); | |
| } | |
| } | |
| return 0; | |
| default: | |
| if (cmd >= 1024 && cmd < 2048) { // palette | |
| colors[cmd-1024] = new Color(arg1, arg2, arg3); | |
| } | |
| if (cmd == 1024) { | |
| pp.setBackground(colors[0]); | |
| if (statusBar != null) statusBar.setBackground(colors[0]); | |
| this.setBackground(colors[0]); | |
| } | |
| return 0; | |
| } | |
| } catch (Throwable ex) { | |
| ex.printStackTrace(); | |
| System.exit(-1); | |
| return 0; | |
| } | |
| } | |
| private void addStatusBar() { | |
| statusBar = new JLabel("test"); | |
| statusBar.setBorder(new BevelBorder(BevelBorder.LOWERED)); | |
| getContentPane().add(BorderLayout.SOUTH,statusBar); | |
| } | |
| // Standalone runner | |
| public static void main(String[] args) { | |
| final PuzzleApplet a = new PuzzleApplet(); | |
| JFrame jf = new JFrame("Loading..."); | |
| jf.getContentPane().setLayout(new BorderLayout()); | |
| jf.getContentPane().add(a, BorderLayout.CENTER); | |
| a.mainWindow=jf; | |
| a.init(); | |
| a.start(); | |
| jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
| jf.addWindowListener(new WindowAdapter() { | |
| public void windowClosing(WindowEvent e) { | |
| a.stop(); | |
| a.destroy(); | |
| } | |
| }); | |
| jf.setVisible(true); | |
| } | |
| public static class PuzzlePanel extends JPanel { | |
| private static final long serialVersionUID = 1L; | |
| protected BufferedImage backBuffer; | |
| public PuzzlePanel() { | |
| setPreferredSize(new Dimension(100,100)); | |
| createBackBuffer(100,100, Color.black); | |
| } | |
| public void createBackBuffer(int w, int h, Color bg) { | |
| if (w > 0 && h > 0) { | |
| backBuffer = new BufferedImage(w,h, BufferedImage.TYPE_3BYTE_BGR); | |
| Graphics g = backBuffer.createGraphics(); | |
| g.setColor(bg); | |
| g.fillRect(0, 0, w, h); | |
| g.dispose(); | |
| } | |
| } | |
| protected void paintComponent(Graphics g) { | |
| g.drawImage(backBuffer, 0, 0, this); | |
| } | |
| } | |
| public static class ConfigComponent { | |
| public int type; | |
| public int configItemPointer; | |
| public JComponent component; | |
| public ConfigComponent(int type, int configItemPointer, JComponent component) { | |
| this.type = type; | |
| this.configItemPointer = configItemPointer; | |
| this.component = component; | |
| } | |
| } | |
| public class ConfigDialog extends JDialog { | |
| private GridBagConstraints gbcLeft = new GridBagConstraints( | |
| GridBagConstraints.RELATIVE, GridBagConstraints.RELATIVE, 1, 1, | |
| 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, | |
| new Insets(0, 0, 0, 0), 0, 0); | |
| private GridBagConstraints gbcRight = new GridBagConstraints( | |
| GridBagConstraints.RELATIVE, GridBagConstraints.RELATIVE, | |
| GridBagConstraints.REMAINDER, 1, 1.0, 0, | |
| GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, | |
| new Insets(5, 5, 5, 5), 0, 0); | |
| private GridBagConstraints gbcBottom = new GridBagConstraints( | |
| GridBagConstraints.RELATIVE, GridBagConstraints.RELATIVE, | |
| GridBagConstraints.REMAINDER, GridBagConstraints.REMAINDER, | |
| 1.0, 1.0, GridBagConstraints.CENTER, | |
| GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0); | |
| private static final long serialVersionUID = 1L; | |
| private List components = new ArrayList(); | |
| public ConfigDialog(JApplet parent, String title) { | |
| super(JOptionPane.getFrameForComponent(parent), title, true); | |
| getContentPane().setLayout(new GridBagLayout()); | |
| } | |
| public void addTextBox(int ptr, String name, String value) { | |
| getContentPane().add(new JLabel(name), gbcLeft); | |
| JComponent c = new JTextField(value, 25); | |
| getContentPane().add(c, gbcRight); | |
| components.add(new ConfigComponent(C_STRING, ptr, c)); | |
| } | |
| public void addCheckBox(int ptr, String name, boolean selected) { | |
| JComponent c = new JCheckBox(name, selected); | |
| getContentPane().add(c, gbcRight); | |
| components.add(new ConfigComponent(C_BOOLEAN, ptr, c)); | |
| } | |
| public void addComboBox(int ptr, String name, String values, int selected) { | |
| getContentPane().add(new JLabel(name), gbcLeft); | |
| StringTokenizer st = new StringTokenizer(values.substring(1), values.substring(0,1)); | |
| JComboBox c = new JComboBox(); | |
| c.setEditable(false); | |
| while(st.hasMoreTokens()) | |
| c.addItem(st.nextToken()); | |
| c.setSelectedIndex(selected); | |
| getContentPane().add(c, gbcRight); | |
| components.add(new ConfigComponent(C_CHOICES, ptr, c)); | |
| } | |
| public void finish() { | |
| JPanel buttons = new JPanel(new GridLayout(1, 2, 5, 5)); | |
| getContentPane().add(buttons, gbcBottom); | |
| JButton b; | |
| buttons.add(b=new JButton("OK")); | |
| b.addActionListener(new ActionListener() { | |
| public void actionPerformed(ActionEvent e) { | |
| save(); | |
| dispose(); | |
| } | |
| }); | |
| getRootPane().setDefaultButton(b); | |
| buttons.add(b=new JButton("Cancel")); | |
| b.addActionListener(new ActionListener() { | |
| public void actionPerformed(ActionEvent e) { | |
| dispose(); | |
| } | |
| }); | |
| setDefaultCloseOperation(DISPOSE_ON_CLOSE); | |
| pack(); | |
| setLocationRelativeTo(null); | |
| setVisible(true); | |
| } | |
| private void save() { | |
| for (int i = 0; i < components.size(); i++) { | |
| ConfigComponent cc = (ConfigComponent) components.get(i); | |
| switch(cc.type) { | |
| case C_STRING: | |
| JTextField jtf = (JTextField)cc.component; | |
| runtimeCall("jcallback_config_set_string", new int[] {cc.configItemPointer, runtime.strdup(jtf.getText())}); | |
| break; | |
| case C_BOOLEAN: | |
| JCheckBox jcb = (JCheckBox)cc.component; | |
| runtimeCall("jcallback_config_set_boolean", new int[] {cc.configItemPointer, jcb.isSelected()?1:0}); | |
| break; | |
| case C_CHOICES: | |
| JComboBox jcm = (JComboBox)cc.component; | |
| runtimeCall("jcallback_config_set_choice", new int[] {cc.configItemPointer, jcm.getSelectedIndex()}); | |
| break; | |
| } | |
| } | |
| runtimeCall("jcallback_config_ok", new int[0]); | |
| } | |
| } | |
| } | |