diff --git a/src/edu/csus/ecs/pc2/ui/ShadowCompareRunsFrame.java b/src/edu/csus/ecs/pc2/ui/ShadowCompareRunsFrame.java index 34f34e57e..e15495341 100644 --- a/src/edu/csus/ecs/pc2/ui/ShadowCompareRunsFrame.java +++ b/src/edu/csus/ecs/pc2/ui/ShadowCompareRunsFrame.java @@ -1,4 +1,4 @@ -// Copyright (C) 1989-2019 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau. +// Copyright (C) 1989-2024 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau. package edu.csus.ecs.pc2.ui; import java.awt.Dimension; @@ -16,17 +16,17 @@ public class ShadowCompareRunsFrame extends JFrame { private static final long serialVersionUID = 1L; - public ShadowCompareRunsFrame(ShadowController shadowController) { setMinimumSize(new Dimension(750, 900)); Dimension size = new Dimension(750,750); this.setPreferredSize(size); // this.setMinimumSize(size); - + ShadowCompareRunsPane runsPane = new ShadowCompareRunsPane(shadowController); runsPane.setMinimumSize(new Dimension(750, 900)); runsPane.setPreferredSize(new Dimension(750, 900)); - + + // runsPane.setContestAndController(shadowController.getLocalContest(), shadowController.getLocalController()); //the above statement was moved into the ShadowCompareRunsPane() constructor, as follows: // this.setContestAndController(shadowController.getLocalContest(), shadowController.getLocalController()); @@ -38,4 +38,5 @@ public ShadowCompareRunsFrame(ShadowController shadowController) { this.getContentPane().add(runsPane); } + } diff --git a/src/edu/csus/ecs/pc2/ui/ShadowCompareRunsPane.java b/src/edu/csus/ecs/pc2/ui/ShadowCompareRunsPane.java index c96243c5f..a16c2939b 100644 --- a/src/edu/csus/ecs/pc2/ui/ShadowCompareRunsPane.java +++ b/src/edu/csus/ecs/pc2/ui/ShadowCompareRunsPane.java @@ -77,16 +77,16 @@ public class ShadowCompareRunsPane extends JPanePlugin { private static final long serialVersionUID = 1L; - + private static final int RUN_UPDATE_REQUEST_SERVER_TIMEOUT_MILLIS = 30000; - + private static final String DEFAULT_REFRESH_INTERVAL = "5"; - + private ShadowController shadowController = null ; - + //the current judgement information from the shadow controller private Map currentJudgementMap = null; - + private Map filteredJudgementMap = null; //the table displaying the current results @@ -102,16 +102,16 @@ public class ShadowCompareRunsPane extends JPanePlugin { private Run runWeRequestedServerToUpdate; private boolean serverHasUpdatedOurRun; - + private JPanel dynamicallyRefreshPanel; - + private JCheckBox mismatchCheckBox; @Override public String getPluginTitle() { return "Shadow_Compare_Pane"; } - + /** * This GUI class accepts a reference to a {@link ShadowController}, from which it obtains (by calling * {@link ShadowController#getJudgementComparisonInfo()}) a @@ -127,11 +127,10 @@ public ShadowCompareRunsPane(ShadowController shadowController) { Dimension size = new Dimension(700,700); this.setPreferredSize(size); this.setMinimumSize(size); - this.shadowController = shadowController ; - + this.log = shadowController.getLog(); - + this.setContestAndController(shadowController.getLocalContest(), shadowController.getLocalController()); //add a run listener so we can be notified when run edits which we invoke (during the "Resolve Run" operation) are completed @@ -141,28 +140,33 @@ public ShadowCompareRunsPane(ShadowController shadowController) { JLabel header = new JLabel("Comparison of PC2 vs. Remote Judgements"); header.setAlignmentX(Component.CENTER_ALIGNMENT); this.add(header); - + + shadowController.setFilter(FILTERS.NONE);//Required to reset the state of the filter //get the framework for the table which will be used to display comparison results resultsTable = getResultsTable(); - + //put the current comparison results into the table model resultsTable.setModel(getUpdatedResultsTableModel()); - + //support sorting the table by clicking on the column headers TableRowSorter sorter = new TableRowSorter(resultsTable.getModel()); resultsTable.setRowSorter(sorter); resultsTable.setAutoCreateRowSorter(true); //necessary to allow updated model to display and sort correctly - + //put the results table in a scrollpane on the GUI JScrollPane scrollPane = new JScrollPane(resultsTable, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + + this.add(scrollPane); this.add(getSummaryPanel()); - + this.add(getdynamicallyRefreshPanel()); - + this.add(getButtonPanel()); + + } /** @@ -179,7 +183,7 @@ private JTable getResultsTable() { JTable resultsTable = new JTable() { private static final long serialVersionUID = 1L; - + private Border outside = new MatteBorder(1, 0, 1, 0, Color.RED); private Border inside = new EmptyBorder(0, 1, 0, 1); private Border highlight = new CompoundBorder(outside, inside); @@ -207,7 +211,7 @@ public Component prepareRenderer(TableCellRenderer renderer, int row, int column (remoteJudgement != null && remoteJudgement.toLowerCase().contains("pending"))) { c.setBackground(new Color(255, 255, 153)); } - + // update font to bold & italic if row is selected if (isRowSelected(row)) { c.setFont(new Font("Arial Bold", Font.ITALIC, 14)); @@ -216,7 +220,7 @@ public Component prepareRenderer(TableCellRenderer renderer, int row, int column return c; } - + //we don't want any of the results cells to be editable public boolean isCellEditable(int nRow, int nCol) { return false; @@ -228,7 +232,7 @@ public boolean isCellEditable(int nRow, int nCol) { centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); resultsTable.setDefaultRenderer(String.class, centerRenderer); resultsTable.setDefaultRenderer(Integer.class, centerRenderer); - + resultsTable.setRowSelectionAllowed(true); resultsTable.setColumnSelectionAllowed(false); resultsTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); @@ -455,6 +459,7 @@ public void run() { dynamicallyRefreshPanel.add(getmismatchCheckBox()); } + return dynamicallyRefreshPanel; } diff --git a/src/edu/csus/ecs/pc2/ui/ShadowCompareScoreboardFrame.java b/src/edu/csus/ecs/pc2/ui/ShadowCompareScoreboardFrame.java index b3363906c..6bf654c43 100644 --- a/src/edu/csus/ecs/pc2/ui/ShadowCompareScoreboardFrame.java +++ b/src/edu/csus/ecs/pc2/ui/ShadowCompareScoreboardFrame.java @@ -1,4 +1,4 @@ -// Copyright (C) 1989-2019 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau. +// Copyright (C) 1989-2024 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau. package edu.csus.ecs.pc2.ui; import java.awt.Dimension; @@ -21,7 +21,10 @@ public ShadowCompareScoreboardFrame(ShadowController shadowController) { Dimension size = new Dimension(1200,900); this.setPreferredSize(size); this.setMinimumSize(size); + this.getContentPane().add(new ShadowCompareScoreboardPane(shadowController)); } + + } diff --git a/src/edu/csus/ecs/pc2/ui/ShadowControlPane.java b/src/edu/csus/ecs/pc2/ui/ShadowControlPane.java index 87bd43a3a..5a3c387e3 100644 --- a/src/edu/csus/ecs/pc2/ui/ShadowControlPane.java +++ b/src/edu/csus/ecs/pc2/ui/ShadowControlPane.java @@ -144,6 +144,8 @@ public class ShadowControlPane extends JPanePlugin implements IShadowMonitorStat "CLICS state message with a non-null started property is received." + "

Do you wish to continue and start shadowing anyway?"; + private ShadowCompareRunsFrame shadowCompareRunsFrame; + private ShadowCompareScoreboardFrame shadowCompareScoreboardFrame; // Status column for JTable notifications enum ShadowStatus { SUCCESS, @@ -884,13 +886,21 @@ public void actionPerformed(java.awt.event.ActionEvent e) { showErrorMessage("No shadow controller available; cannot show runs comparison", "Missing Controller"); } else if (!ShadowController.SHADOW_CONTROLLER_STATUS.SC_RUNNING.equals(shadowController.getStatus())) { showErrorMessage("Cannot compare runs, shadow not running","Shadow not running"); - } else { - JFrame shadowCompareRunsFrame = new ShadowCompareRunsFrame(shadowController); + } else if (shadowCompareRunsFrame != null && shadowCompareRunsFrame.isVisible()) { + showErrorMessage("Compare Runs already open", "Compare Runs Already Open"); + shadowCompareRunsFrame.setState(JFrame.NORMAL); //If the frame was minimized this brings it back. + shadowCompareRunsFrame.setVisible(false); // This was recommended to make it work for MacOS + shadowCompareRunsFrame.setVisible(true); + shadowCompareRunsFrame.toFront(); + shadowCompareRunsFrame.requestFocus(); + }else { + shadowCompareRunsFrame = new ShadowCompareRunsFrame(shadowController); shadowCompareRunsFrame.setSize(600,700); shadowCompareRunsFrame.setLocationRelativeTo(null); // centers frame shadowCompareRunsFrame.setTitle("Shadow Run Comparison"); shadowCompareRunsFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); shadowCompareRunsFrame.setVisible(true); + } } @@ -919,8 +929,16 @@ public void run() { showErrorMessage("No shadow controller available; cannot show scoreboard comparison", "Missing Controller"); } else if (!ShadowController.SHADOW_CONTROLLER_STATUS.SC_RUNNING.equals(shadowController.getStatus())) { showErrorMessage("Cannot compare scoreboard, shadow not running","Shadow not running"); - } else { - JFrame shadowCompareScoreboardFrame = new ShadowCompareScoreboardFrame(shadowController); + } else if (shadowCompareScoreboardFrame != null && shadowCompareScoreboardFrame.isVisible()) { + showErrorMessage("Compare Scoreboards already open", "Compare Scoreboards Already Open"); + shadowCompareScoreboardFrame.setState(JFrame.NORMAL); //If the frame was minimized this brings it back. + shadowCompareScoreboardFrame.setVisible(false); // This was recommended to make it work for MacOS + shadowCompareScoreboardFrame.setVisible(true); + shadowCompareScoreboardFrame.toFront(); + shadowCompareScoreboardFrame.requestFocus(); + } + else { + shadowCompareScoreboardFrame = new ShadowCompareScoreboardFrame(shadowController); shadowCompareScoreboardFrame.setSize(600,700); shadowCompareScoreboardFrame.setLocationRelativeTo(null); // centers frame shadowCompareScoreboardFrame.setTitle("Shadow Scoreboard Comparison");