From ccf80a173c604394c507d6ab28c7da1e0477dcac Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Tue, 8 Nov 2022 16:23:42 -0800 Subject: [PATCH 01/10] Currently refactoring and making changes to interface. Doing bug fixes. --- .../main/java/edu/abc/berkeley/PWZGUI.java | 149 ++++++++++-------- 1 file changed, 84 insertions(+), 65 deletions(-) diff --git a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java index 9d94578..d447458 100644 --- a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java +++ b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java @@ -53,6 +53,31 @@ * - Compressor default is lz4 not iz4. */ +/* + * HOW TO RESIZES WIDGETS (MEETING NOTES) + * --> Using custom grid layouts. (For future ref, for resizeable widgets) + * + * FLow should work (Refactor) + +What should the interface do actually do? + + * - Remove crop button. (Should use coordinates) [DONE] + * 1.) Should be able to browse even without typing the filepath [DONE] + * 2.) Filepath taking in the value from file.getPath(). [???] + * 3.) Update text area and this.filepath when browsing to a file. [DONE] + * 4.) Keep in mind: lz4 should be an editable text box (like the filepath text area) [DONE] + * 5.) Save changes to submit, and set location to be at the bottom of the window. + * 6.) Submit button clicked, then should quit out of the form. (Close this JFrame only, not the entire software) + * + * VARIABLES + * - Add in the constructor params ImageStack array, in the constructor. + * - Take out default values variables in update table. + * + * What to check for? (Error Checking) + * - Check for only .zarr file. (If not, then display error message), these are the only error-checking required right now. + * + */ + /* C++ MAIN PROJECT. * 1.) Release and get matlab working with C++ Qt (version, 6.2.4) @@ -62,16 +87,16 @@ public class PWZGUI implements ActionListener{ JFrame window; JPanel textAreaPanel; - JButton browse; - - // Crop check box - JLabel checkboxLabel; - JCheckBox checkBox; + JButton browse; // Browse specific filepath. // Text box JLabel textAreaLabel; JTextArea textArea; + // For compressor lz4 + JTextArea compressTextArea;// Compressor Text Area + JLabel compressorLabel; // Default Compressor + // Starting and ending XYZ JTable table; JScrollPane scrollPane; @@ -89,17 +114,21 @@ public class PWZGUI implements ActionListener{ // Also, not reusing other starting and ending, so doesnt alter those variables. public long chunkSizeX=256, chunkSizeY=256, chunkSizeZ=256; + public ImageStack imageStack; + + public Object[] cImageObj; + JTable chunkTable; // Displaying the chunk sizes that are the default XYZ coords. (Though not expected to be changed.) JScrollPane chunkScrollPane; // Scroll pane, to help display the default values of the chunk size. - // Default Compressor - JLabel compressorLabel; + - JButton saveChangesButton; // To save changes when + JButton submitButton; // To submit changes, then close this specific interface. (Not the entire software.) public PWZGUI() { filepath = ""; compressor = "lz4"; // Compressor is lz4. (NOTE, this value does not change by default whatsoever) + imageStack = null; // Starting coords // Starting and ending coordinates are the expected values to be changed by user using the intercface. @@ -133,9 +162,11 @@ public void run(){ // This commented constructor was just an idea (will deleted, if this implementation may not be needed.) // public PWZGUI(String filepath, Coords starting, Coords ending, String compressor){ - public PWZGUI(String filepath, long startX, long startY, long startZ, long endX, long endY, long endZ, long chunkSizeX, long chunkSizeY, long chunkSizeZ, String compressor){ + public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, long startZ, long endX, long endY, long endZ, long chunkSizeX, long chunkSizeY, long chunkSizeZ, String compressor){ this.filepath = filepath; this.compressor = compressor; + this.imageStack = imageStack; + this.cImageObj = imageStack.getImageArray(); // Is this how we want to pass in an array // Starting coords this.startX = startX; @@ -167,14 +198,14 @@ private void init(){ window = new JFrame("Write Zarr"); textAreaPanel = new JPanel(); // Main Panel compressorLabel = new JLabel(); + compressTextArea = new JTextArea(); setupTextProperties(); // Handling button widget - setupCropProperties(); // User type text label, and text box field. grabCoordinates(); chunkAndCompressorProperties(); - saveChangesButton(); // update the table changes. + submitButton(); // Submit button: What this does is submit the given changes, then close this specific interface. show(); // Handling adding all the widgets into the panel, while panel is being referred by the JFrame. // Setting window/jframe properties @@ -197,23 +228,17 @@ private void setupTextProperties(){ textArea.setLayout(new FlowLayout()); } - - // Setup cropping properties and JLabels corresponding to given check box widget. - private void setupCropProperties(){ - // User type text label, and text box field. - checkBox = new JCheckBox("Crop"); - checkBox.setBounds(160, 110, 75, 15); // Higher x is more to the right we go, lower value y is the more we go upwards. - checkBox.addActionListener(this); - } private void grabCoordinates(){ // Labels allowing the user using the interface to know startCoordsLabel = new JLabel("Start"); endCoordsLabel = new JLabel("End"); - startCoordsLabel.setBounds(115, 90, 150, 150); - endCoordsLabel.setBounds(115, 110, 150, 150); - + // startCoordsLabel.setBounds(115, 90, 150, 150); + // endCoordsLabel.setBounds(115, 110, 150, 150); + startCoordsLabel.setBounds(140, 5, 150, 150); + endCoordsLabel.setBounds(145, 20, 150, 150); + Object[][] data = { {startX, startY, startZ}, {endX, endY, endZ}, @@ -228,7 +253,8 @@ public boolean isCellEditable(int row, int col) { }; table = new JTable(tableModel); - table.setBounds(30, 30, 950, 950); + // table.setBounds(30, 30, 950, 950); + table.setBounds(235, 55, 115, 25); // Adding columns to the table tableModel.addColumn("X"); @@ -240,7 +266,8 @@ public boolean isCellEditable(int row, int col) { scrollPane = new JScrollPane(table); scrollPane.setPreferredSize(new Dimension(250, 100)); // Actually setting how large the scroll pane is. - scrollPane.setBounds(172, 145, 250, 53); // Set where we want the JTable to be located in the JFrame. (Actually adjusts X and Y coords, and width and height) + // scrollPane.setBounds(172, 145, 250, 53); // Set where we want the JTable to be located in the JFrame. (Actually adjusts X and Y coords, and width and height) + scrollPane.setBounds(195, 55, 230, 53); scrollPane.setVisible(true); } @@ -261,20 +288,26 @@ private void chunkAndCompressorProperties(){ chunkScrollPane = new JScrollPane(chunkTable); // Original width = 210, height = 75 chunkScrollPane.setPreferredSize(new Dimension(200, 100)); // Actually setting how large the scroll pane is. - chunkScrollPane.setBounds(170, 205, 255, 40); // Set where we want the JTable to be located in the JFrame. (This line is what updates the X, Y coordinates of widget) + // chunkScrollPane.setBounds(170, 205, 255, 40); // Set where we want the JTable to be located in the JFrame. (This line is what updates the X, Y coordinates of widget) + chunkScrollPane.setBounds(195, 125, 230, 53); // Set where we want the JTable to be located in the JFrame. (This line is what updates the X, Y coordinates of widget) chunkScrollPane.setVisible(true); - compressorLabel.setText("Compressor: " + compressor); + // Compressor = default is lz4 (though the user, should also be able to change the default as an option as well) + compressorLabel.setText("Compressor: "); compressorLabel.setBounds(180, 245, 130, 20); // NOTE: Higher the Y-axis lower widgets are positioned. Higher X axis, more to right the widgets positioned at. + + compressTextArea.setText(compressor); + // compressTextArea.setBounds(265,245, 65, 19); + compressTextArea.setBounds(210,155, 65, 19); } // Function to help organize the widget that handles the saving changes button. - private void saveChangesButton() { - saveChangesButton = new JButton("Save Changes"); + private void submitButton() { + submitButton = new JButton("Save Changes"); // saveChangesButton.setBounds(230, 55, 115, 25); - saveChangesButton.setBounds(235, 55, 115, 25); + submitButton.setBounds(235, 55, 115, 25); - saveChangesButton.addActionListener(this); + submitButton.addActionListener(this); } // show function, has keeps track of all the added components into JFrame -> going to -> JPanel -> widgets/checkboxes/etc. @@ -289,51 +322,42 @@ private void show(){ textAreaPanel.setSize(50, 50); // Adds the other widgets into the JFrame window themselves. - window.add(checkBox); // UPDATE: Add this into the window frame. So we can move this widget however we see fit. window.add(startCoordsLabel); window.add(endCoordsLabel); window.add(scrollPane); window.add(chunkScrollPane); window.add(compressorLabel); + window.add(compressTextArea); - window.add(saveChangesButton); + window.add(submitButton); // Setting window/jframe properties - window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + // window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.add(textAreaPanel, BorderLayout.CENTER); // This is how the TextArea and Labels, are being centered to the TOP of the interface. window.pack(); window.setLocation(new Point(900, 250)); // Hopefully puts the screen in the center of the monitor (vary depending on monitoring) window.setVisible(true); - // window.setResizable(false); } // Handling events happening with the interface. @Override public void actionPerformed(ActionEvent e){ - String filepath = textArea.getText(); - boolean emptyString = filepath.equals(""); // We dont want to browse anything that isn't a string. (Don't assume, everyone will type the right input. Just precautionary) - - // Just add this just in case, we do not want empty characters - if(emptyString) return; + // this.filepath = textArea.getText(); - if(e.getSource() == browse){ - // We want to check if the checkbox is clicked before we compress that file. - if(checkBox.isSelected()) checkboxClicked(); - if(!emptyString) loadfile(filepath); - } + if(e.getSource() == browse) loadfile(); // We want to check if the checkbox is clicked before we compress that file. // Updates and clears the table. - if(e.getSource() == saveChangesButton) updateTable(); + if(e.getSource() == submitButton) updateTable(); // Updates the table when we submit the changes, and then is the function that quits out the JFrame for this specific interface. } // Loading filepath given. - private void loadfile(String filepath){ + private void loadfile(){ // File Handling stuff. (Referenced PWZ.java) - // PWZC pwzc = new PWZC(); + // PWZC pwzc = new PWZC(); // This code is only used to call the C-functionality... JFileChooser chooser = new JFileChooser(); chooser.setApproveButtonText("Save"); chooser.setDialogTitle("Save as Zarr"); @@ -348,7 +372,9 @@ private void loadfile(String filepath){ if(cImagePlus == null) return; - ImageStack cImageStack = cImagePlus.getImageStack(); + //--> We are replacing this piece of code, with an this.imageStack that is being passed an imageStack in the constructor. <-- + + /*ImageStack cImageStack = cImagePlus.getImageStack(); Object[] cImageObj = cImageStack.getImageArray(); @@ -356,28 +382,19 @@ private void loadfile(String filepath){ String fileName = file.getPath(); int x = cImageStack.getWidth(); int y = cImageStack.getHeight(); - int z = cImageStack.getSize(); + int z = cImageStack.getSize();*/ + + // This code will replace the commented code at the top. + this.filepath = file.getPath(); // This updates the filepath // pwzc.parallelWriteZarr(fileName, cImageObj, 0, 0, 0, y, x, z, 256, 256, 256, 1, "lz4", 1, bits); } - - private void checkboxClicked(){ System.out.println("[DEBUGGING]: Check Box Clicked!"); } // Does smthing when this check box is clicked. - - // When "Save Changes" button is clicked, the given inputted information is updated - // Little redundant, for now was trying to get interface working with updating the JTable. + // When "Submit changes" button is clicked, the given inputted information is updated private void updateTable(){ - startX = 123; - startY = 456; - startZ = 890; - - endX = 1024; - endY = 1036; - endZ = 1048; - chunkSizeX = 256; - chunkSizeY = 256; - chunkSizeZ = 256; + // This code will replace the commented code at the top. + textArea.setText(this.filepath); table.getModel().setValueAt(startX, 0, 0); table.getModel().setValueAt(startY, 0, 1); @@ -389,8 +406,10 @@ private void updateTable(){ chunkTable.getModel().setValueAt(chunkSizeX, 0, 0); chunkTable.getModel().setValueAt(chunkSizeY, 0, 1); chunkTable.getModel().setValueAt(chunkSizeZ, 0, 2); + + window.dispose(); // Dispose() is how we will exit, once the submit changes have been made. } // For testing and debugging the interface with a main method. - // public static void main(String[] args) { new PWZGUI(); } + // public static void main(String[] args) { new PWZGUI(); } } \ No newline at end of file From b7756d1be09b99b48322b4b9c517728720bf7c79 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Thu, 10 Nov 2022 00:38:08 -0800 Subject: [PATCH 02/10] Refactored interface and added an error message dialog if files not zarr --- .../main/java/edu/abc/berkeley/PWZGUI.java | 54 +++++++++++-------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java index d447458..2cc14b4 100644 --- a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java +++ b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java @@ -13,6 +13,7 @@ import java.awt.event.ActionEvent; import java.io.File; +import java.nio.file.Files; /* * PREVIOUS MEETING DISCUSSION @@ -118,6 +119,8 @@ public class PWZGUI implements ActionListener{ public Object[] cImageObj; + public int bits; + JTable chunkTable; // Displaying the chunk sizes that are the default XYZ coords. (Though not expected to be changed.) JScrollPane chunkScrollPane; // Scroll pane, to help display the default values of the chunk size. @@ -146,6 +149,8 @@ public PWZGUI() { chunkSizeY = 256; chunkSizeZ = 256; + bits = 0; + // Creates a thread. Lets be called and execute object in its own instance. // Basically like its own thread. Runnable r = new Runnable() { @@ -162,7 +167,7 @@ public void run(){ // This commented constructor was just an idea (will deleted, if this implementation may not be needed.) // public PWZGUI(String filepath, Coords starting, Coords ending, String compressor){ - public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, long startZ, long endX, long endY, long endZ, long chunkSizeX, long chunkSizeY, long chunkSizeZ, String compressor){ + public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, long startZ, long endX, long endY, long endZ, long chunkSizeX, long chunkSizeY, long chunkSizeZ, String compressor, int bits){ this.filepath = filepath; this.compressor = compressor; this.imageStack = imageStack; @@ -181,6 +186,8 @@ public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, this.chunkSizeY = chunkSizeY; this.chunkSizeZ = chunkSizeZ; + this.bits = bits; + // Creates a thread. Lets be called and execute object in its own instance. // Basically like its own thread. Runnable r = new Runnable(){ @@ -294,22 +301,29 @@ private void chunkAndCompressorProperties(){ // Compressor = default is lz4 (though the user, should also be able to change the default as an option as well) compressorLabel.setText("Compressor: "); - compressorLabel.setBounds(180, 245, 130, 20); // NOTE: Higher the Y-axis lower widgets are positioned. Higher X axis, more to right the widgets positioned at. + compressorLabel.setBounds(180, 195, 130, 20); // NOTE: Higher the Y-axis lower widgets are positioned. Higher X axis, more to right the widgets positioned at. compressTextArea.setText(compressor); // compressTextArea.setBounds(265,245, 65, 19); - compressTextArea.setBounds(210,155, 65, 19); + compressTextArea.setBounds(265,195, 65, 19); } // Function to help organize the widget that handles the saving changes button. private void submitButton() { submitButton = new JButton("Save Changes"); // saveChangesButton.setBounds(230, 55, 115, 25); - submitButton.setBounds(235, 55, 115, 25); - + // submitButton.setBounds(212, 55, 115, 25); + submitButton.setBounds(175, 225, 115, 25); submitButton.addActionListener(this); } + // Display error message window, if the file is not a zarr file. + private void errorMessage(){ + String message = "File must be a zarr file"; + // JOptionPane.showInputDialog(message); + JOptionPane.showMessageDialog(window, message); + } + // show function, has keeps track of all the added components into JFrame -> going to -> JPanel -> widgets/checkboxes/etc. private void show(){ // NOTE: Add to panel @@ -346,10 +360,7 @@ private void show(){ // Handling events happening with the interface. @Override public void actionPerformed(ActionEvent e){ - // this.filepath = textArea.getText(); - if(e.getSource() == browse) loadfile(); // We want to check if the checkbox is clicked before we compress that file. - // Updates and clears the table. if(e.getSource() == submitButton) updateTable(); // Updates the table when we submit the changes, and then is the function that quits out the JFrame for this specific interface. } @@ -357,7 +368,7 @@ public void actionPerformed(ActionEvent e){ // Loading filepath given. private void loadfile(){ // File Handling stuff. (Referenced PWZ.java) - // PWZC pwzc = new PWZC(); // This code is only used to call the C-functionality... + // PWZC pwzc = new PWZC(); // This code is only used to call the C-functionality... (Wont work on mac, so comment out in the meantime.) JFileChooser chooser = new JFileChooser(); chooser.setApproveButtonText("Save"); chooser.setDialogTitle("Save as Zarr"); @@ -372,28 +383,27 @@ private void loadfile(){ if(cImagePlus == null) return; - //--> We are replacing this piece of code, with an this.imageStack that is being passed an imageStack in the constructor. <-- + // pwzc.parallelWriteZarr(this.filepath, this.cImageObj, this.startX, this.startY, this.startZ, this.endX, this.endY, this.endZ, this.chunkSizeX, this.chunkSizeY, this.chunkSizeZ, 1, this.compressor, 1, this.bits); + } - /*ImageStack cImageStack = cImagePlus.getImageStack(); - Object[] cImageObj = cImageStack.getImageArray(); + private boolean checkExtension(String path){ + String extension = ""; + int i = path.lastIndexOf('.'); - - int bits = cImageStack.getBitDepth(); // May need to get bits another way - String fileName = file.getPath(); - int x = cImageStack.getWidth(); - int y = cImageStack.getHeight(); - int z = cImageStack.getSize();*/ + if(i != -1) extension = path.substring(i+1); - // This code will replace the commented code at the top. - this.filepath = file.getPath(); // This updates the filepath + // System.out.println("LOGGER: " + extension + ", i = " + i); // For debugging purposes. + + if(extension.equals("zarr")) return true; - // pwzc.parallelWriteZarr(fileName, cImageObj, 0, 0, 0, y, x, z, 256, 256, 256, 1, "lz4", 1, bits); + return false; } // When "Submit changes" button is clicked, the given inputted information is updated private void updateTable(){ - // This code will replace the commented code at the top. + // Checks if the text area box is a zarr file, or the filepath we load in from the browser button are a zarr file. If not display error message. + if(!checkExtension(this.filepath) && !checkExtension(textArea.getText())) errorMessage(); textArea.setText(this.filepath); table.getModel().setValueAt(startX, 0, 0); From c152a1daeca8f0b9f9447076857af24852463ed4 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Fri, 11 Nov 2022 14:48:10 -0800 Subject: [PATCH 03/10] Refactored interface and added an error message dialog if files not zarr --- .../main/java/edu/abc/berkeley/PWZGUI.java | 62 ++++--------------- 1 file changed, 12 insertions(+), 50 deletions(-) diff --git a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java index 2cc14b4..8021fa2 100644 --- a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java +++ b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java @@ -13,74 +13,36 @@ import java.awt.event.ActionEvent; import java.io.File; -import java.nio.file.Files; - -/* - * PREVIOUS MEETING DISCUSSION - * - Implement constructor that takes in this many arguments. (As shown below) - * ** PWZGUI(string, long, long, long, long, long, long, long, long, long, string) // filepath: string, Starting XYZ: long, ending XYZ: long, chunkSize: long, compressor: string - * CHANGES NEEDED TO BE MADE TO THE INTERFACE - * 1.) Crop Button. By brinding down the crop box, and positioning the widgets similarily to what is being shown in the XML diagrams that we discussed and promptly designed in diagrams.io - * --> Purpose: Cropping the file size of the zarr file we are trying to load by clicking the browse widget. - * 2.) Bring Down and adjust crop widget. Crop widget adjust to the XML formatting. (near/in front of starting and ending XYZ) - * 3.) Make Starting and ending XYZ, with chunk and default compressor seperate from each other - - * SIDE NOTE: (Describing by thought process.) - * 1. table for starting & ending XYZ - * 2. another for chunk and compressor. - * NOTE: Dont actually write default, just put compressor. - */ /* * NOTES - * 1.) Fix interface to look similarily to the wxWidget diagram from diagram.io (DONE) - * 2.) [IMPORTANT] Integrate the JFileChooser to being used by this interface. (DONE) - * 3.) Seperate Chunk Size and Compressor into their own rows and cols fields. (DONE) - * SOMETHING TO NOTE: Dont actually write default, just put compressor. - * 4.) Re-adjusting the crop file size widget to a similar position referenced to the diagrams.io design. (DONE) - * 5.) Once implemented. Refactor and clean up code. Debugging and troubleshooting, so there is no unecessary code not being used. (DONE) - * - * IN-MEETING DISCUSSION - * - Proposing there be a coordinates class. So, instead of passing in 6 variables, we can pass two objects. Also for better readability to the programmer. - * - Easier to handly the X,Y, and Z coordinates. - * - Or we can keep both implementation, in case we may need to edit the specific values directly, possibly. + * 1.) Fix interface to look similarily to the wxWidget diagram from diagram.io [DONE] + * 2.) [IMPORTANT] Integrate the JFileChooser to being used by this interface. [DONE] + * 3.) Seperate Chunk Size and Compressor into their own rows and cols fields. [DONE] + * SOMETHING TO NOTE: Dont actually write default, just put compressor. [DONE] + * 4.) Re-adjusting the crop file size widget to a similar position referenced to the diagrams.io design. [DONE] + * 5.) Once implemented. Refactor and clean up code. Debugging and troubleshooting, so there is no unecessary code not being used. [DONE] */ - /* - * WRAP UP NOTES FOR THIS PROJECT - * - Constructor chnage variable names (like start_x to startX) - * - Change default_x to chunkX - * - Submit button to make changes. - * - Compressor default is lz4 not iz4. -*/ - /* * HOW TO RESIZES WIDGETS (MEETING NOTES) * --> Using custom grid layouts. (For future ref, for resizeable widgets) - * * FLow should work (Refactor) What should the interface do actually do? +TASKS [Current] * - Remove crop button. (Should use coordinates) [DONE] * 1.) Should be able to browse even without typing the filepath [DONE] * 2.) Filepath taking in the value from file.getPath(). [???] * 3.) Update text area and this.filepath when browsing to a file. [DONE] * 4.) Keep in mind: lz4 should be an editable text box (like the filepath text area) [DONE] - * 5.) Save changes to submit, and set location to be at the bottom of the window. - * 6.) Submit button clicked, then should quit out of the form. (Close this JFrame only, not the entire software) - * - * VARIABLES - * - Add in the constructor params ImageStack array, in the constructor. - * - Take out default values variables in update table. - * - * What to check for? (Error Checking) - * - Check for only .zarr file. (If not, then display error message), these are the only error-checking required right now. - * + * 5.) Save changes to submit, and set location to be at the bottom of the window. [DONE] + * 6.) Submit button clicked, then should quit out of the form. (Close this JFrame only, not the entire software) [DONE] */ /* - C++ MAIN PROJECT. +C++ MAIN PROJECT. * 1.) Release and get matlab working with C++ Qt (version, 6.2.4) */ @@ -119,7 +81,7 @@ public class PWZGUI implements ActionListener{ public Object[] cImageObj; - public int bits; + public long bits; JTable chunkTable; // Displaying the chunk sizes that are the default XYZ coords. (Though not expected to be changed.) JScrollPane chunkScrollPane; // Scroll pane, to help display the default values of the chunk size. @@ -167,7 +129,7 @@ public void run(){ // This commented constructor was just an idea (will deleted, if this implementation may not be needed.) // public PWZGUI(String filepath, Coords starting, Coords ending, String compressor){ - public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, long startZ, long endX, long endY, long endZ, long chunkSizeX, long chunkSizeY, long chunkSizeZ, String compressor, int bits){ + public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, long startZ, long endX, long endY, long endZ, long chunkSizeX, long chunkSizeY, long chunkSizeZ, String compressor, long bits){ this.filepath = filepath; this.compressor = compressor; this.imageStack = imageStack; From cdfb8324f1b11e07516dc08a34f3fcbbe11251e5 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Sun, 13 Nov 2022 23:19:45 -0800 Subject: [PATCH 04/10] Refactor and fixed not updating text box, when user types in filepath and saves changes --- .../main/java/edu/abc/berkeley/PWZGUI.java | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java index 8021fa2..96f1159 100644 --- a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java +++ b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java @@ -88,7 +88,7 @@ public class PWZGUI implements ActionListener{ - JButton submitButton; // To submit changes, then close this specific interface. (Not the entire software.) + JButton saveButton; // To submit changes, then close this specific interface. (Not the entire software.) public PWZGUI() { filepath = ""; @@ -174,7 +174,7 @@ private void init(){ setupTextProperties(); // Handling button widget grabCoordinates(); chunkAndCompressorProperties(); - submitButton(); // Submit button: What this does is submit the given changes, then close this specific interface. + save(); // Submit button: What this does is submit the given changes, then close this specific interface. show(); // Handling adding all the widgets into the panel, while panel is being referred by the JFrame. // Setting window/jframe properties @@ -271,18 +271,16 @@ private void chunkAndCompressorProperties(){ } // Function to help organize the widget that handles the saving changes button. - private void submitButton() { - submitButton = new JButton("Save Changes"); - // saveChangesButton.setBounds(230, 55, 115, 25); - // submitButton.setBounds(212, 55, 115, 25); - submitButton.setBounds(175, 225, 115, 25); - submitButton.addActionListener(this); + // When browsing this save button will update the text box. + private void save() { + saveButton = new JButton("Save Changes"); + saveButton.setBounds(175, 225, 115, 25); + saveButton.addActionListener(this); } // Display error message window, if the file is not a zarr file. private void errorMessage(){ String message = "File must be a zarr file"; - // JOptionPane.showInputDialog(message); JOptionPane.showMessageDialog(window, message); } @@ -306,10 +304,7 @@ private void show(){ window.add(compressTextArea); - window.add(submitButton); - - - + window.add(saveButton); // Setting window/jframe properties // window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); @@ -323,8 +318,11 @@ private void show(){ @Override public void actionPerformed(ActionEvent e){ if(e.getSource() == browse) loadfile(); // We want to check if the checkbox is clicked before we compress that file. + // Updates and clears the table. - if(e.getSource() == submitButton) updateTable(); // Updates the table when we submit the changes, and then is the function that quits out the JFrame for this specific interface. + if(e.getSource() == saveButton) { + updateTable(); // Updates the table when we submit the changes, and then is the function that quits out the JFrame for this specific interface. + } } // Loading filepath given. @@ -345,6 +343,8 @@ private void loadfile(){ if(cImagePlus == null) return; + this.filepath = file.getPath(); + // pwzc.parallelWriteZarr(this.filepath, this.cImageObj, this.startX, this.startY, this.startZ, this.endX, this.endY, this.endZ, this.chunkSizeX, this.chunkSizeY, this.chunkSizeZ, 1, this.compressor, 1, this.bits); } @@ -361,12 +361,13 @@ private boolean checkExtension(String path){ return false; } - // When "Submit changes" button is clicked, the given inputted information is updated + // When "Save" button is clicked, updates interface. private void updateTable(){ - // Checks if the text area box is a zarr file, or the filepath we load in from the browser button are a zarr file. If not display error message. + // Checks if text box is a .zarr file. If not show error msg. if(!checkExtension(this.filepath) && !checkExtension(textArea.getText())) errorMessage(); - textArea.setText(this.filepath); + + textArea.setText(this.filepath); // updates text area. table.getModel().setValueAt(startX, 0, 0); table.getModel().setValueAt(startY, 0, 1); @@ -379,7 +380,7 @@ private void updateTable(){ chunkTable.getModel().setValueAt(chunkSizeY, 0, 1); chunkTable.getModel().setValueAt(chunkSizeZ, 0, 2); - window.dispose(); // Dispose() is how we will exit, once the submit changes have been made. + // window.dispose(); // Dispose() is how we will exit, once the submit changes have been made. } // For testing and debugging the interface with a main method. From 248f2efe0624bd59d06aacf1abccfe189aa2fbc1 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Wed, 16 Nov 2022 00:45:16 -0800 Subject: [PATCH 05/10] Made some finalized changes and did some more refactoring and minor bug fixes --- .../main/java/edu/abc/berkeley/PWZGUI.java | 142 ++++-------------- 1 file changed, 30 insertions(+), 112 deletions(-) diff --git a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java index 96f1159..cfde888 100644 --- a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java +++ b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java @@ -1,11 +1,7 @@ package edu.abc.berkeley; import javax.swing.*; -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; import javax.swing.table.DefaultTableModel; -import ij.IJ; -import ij.ImagePlus; import ij.ImageStack; import java.awt.*; @@ -14,43 +10,11 @@ import java.io.File; -/* - * NOTES - * 1.) Fix interface to look similarily to the wxWidget diagram from diagram.io [DONE] - * 2.) [IMPORTANT] Integrate the JFileChooser to being used by this interface. [DONE] - * 3.) Seperate Chunk Size and Compressor into their own rows and cols fields. [DONE] - * SOMETHING TO NOTE: Dont actually write default, just put compressor. [DONE] - * 4.) Re-adjusting the crop file size widget to a similar position referenced to the diagrams.io design. [DONE] - * 5.) Once implemented. Refactor and clean up code. Debugging and troubleshooting, so there is no unecessary code not being used. [DONE] - */ - -/* - * HOW TO RESIZES WIDGETS (MEETING NOTES) - * --> Using custom grid layouts. (For future ref, for resizeable widgets) - * FLow should work (Refactor) - -What should the interface do actually do? - -TASKS [Current] - * - Remove crop button. (Should use coordinates) [DONE] - * 1.) Should be able to browse even without typing the filepath [DONE] - * 2.) Filepath taking in the value from file.getPath(). [???] - * 3.) Update text area and this.filepath when browsing to a file. [DONE] - * 4.) Keep in mind: lz4 should be an editable text box (like the filepath text area) [DONE] - * 5.) Save changes to submit, and set location to be at the bottom of the window. [DONE] - * 6.) Submit button clicked, then should quit out of the form. (Close this JFrame only, not the entire software) [DONE] - */ - -/* -C++ MAIN PROJECT. - * 1.) Release and get matlab working with C++ Qt (version, 6.2.4) - */ - public class PWZGUI implements ActionListener{ JFrame window; JPanel textAreaPanel; - JButton browse; // Browse specific filepath. + JButton browse; // Browse specific files/folders. // Text box JLabel textAreaLabel; @@ -60,21 +24,21 @@ public class PWZGUI implements ActionListener{ JTextArea compressTextArea;// Compressor Text Area JLabel compressorLabel; // Default Compressor - // Starting and ending XYZ + JTable table; JScrollPane scrollPane; - // Data retrievers. JLabel startCoordsLabel; JLabel endCoordsLabel; public String filepath; public String compressor; + + // Starting and ending XYZ public long startX=0, startY=0, startZ=0; public long endX=0, endY=0, endZ=0; // Default values for the chunk sizes. - // Also, not reusing other starting and ending, so doesnt alter those variables. public long chunkSizeX=256, chunkSizeY=256, chunkSizeZ=256; public ImageStack imageStack; @@ -83,25 +47,18 @@ public class PWZGUI implements ActionListener{ public long bits; - JTable chunkTable; // Displaying the chunk sizes that are the default XYZ coords. (Though not expected to be changed.) - JScrollPane chunkScrollPane; // Scroll pane, to help display the default values of the chunk size. + JTable chunkTable; // Table to show Chunk Size XYZ. (Changeable) + JScrollPane chunkScrollPane; - - - JButton saveButton; // To submit changes, then close this specific interface. (Not the entire software.) + JButton saveButton; // save changes public PWZGUI() { filepath = ""; - compressor = "lz4"; // Compressor is lz4. (NOTE, this value does not change by default whatsoever) + compressor = "lz4"; // Default expected to be lz4. (Is changeable) imageStack = null; - - // Starting coords - // Starting and ending coordinates are the expected values to be changed by user using the intercface. startX = 0; startY = 0; startZ = 0; - - // Ending coords endX = 0; endY = 0; endZ = 0; @@ -126,9 +83,7 @@ public void run(){ // http://docs.oracle.com/javase/tutorial/uiswing/concurrency SwingUtilities.invokeLater(r); } - - // This commented constructor was just an idea (will deleted, if this implementation may not be needed.) - // public PWZGUI(String filepath, Coords starting, Coords ending, String compressor){ + public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, long startZ, long endX, long endY, long endZ, long chunkSizeX, long chunkSizeY, long chunkSizeZ, String compressor, long bits){ this.filepath = filepath; this.compressor = compressor; @@ -161,23 +116,19 @@ public void run(){ SwingUtilities.invokeLater(r); } - + private void init(){ - window = new JFrame("Write Zarr"); textAreaPanel = new JPanel(); // Main Panel compressorLabel = new JLabel(); compressTextArea = new JTextArea(); - - setupTextProperties(); // Handling button widget grabCoordinates(); chunkAndCompressorProperties(); - save(); // Submit button: What this does is submit the given changes, then close this specific interface. - show(); // Handling adding all the widgets into the panel, while panel is being referred by the JFrame. + save(); // Save: What this does is submit the given changes, then close this specific interface. + show(); // Just adds in buttons to frame. - // Setting window/jframe properties window.setSize(600, 300); window.setVisible(true); } @@ -190,7 +141,7 @@ private void setupTextProperties(){ // Handling text box and label textAreaLabel = new JLabel("Filepath"); - textAreaLabel.setBounds(125, 5, 75, 15); + textAreaLabel.setBounds(125, 5, 90, 15); textArea = new JTextArea(1, 6); textArea.setBounds(215, 5, 75, 25); @@ -203,8 +154,6 @@ private void grabCoordinates(){ startCoordsLabel = new JLabel("Start"); endCoordsLabel = new JLabel("End"); - // startCoordsLabel.setBounds(115, 90, 150, 150); - // endCoordsLabel.setBounds(115, 110, 150, 150); startCoordsLabel.setBounds(140, 5, 150, 150); endCoordsLabel.setBounds(145, 20, 150, 150); @@ -222,7 +171,6 @@ public boolean isCellEditable(int row, int col) { }; table = new JTable(tableModel); - // table.setBounds(30, 30, 950, 950); table.setBounds(235, 55, 115, 25); // Adding columns to the table @@ -235,7 +183,6 @@ public boolean isCellEditable(int row, int col) { scrollPane = new JScrollPane(table); scrollPane.setPreferredSize(new Dimension(250, 100)); // Actually setting how large the scroll pane is. - // scrollPane.setBounds(172, 145, 250, 53); // Set where we want the JTable to be located in the JFrame. (Actually adjusts X and Y coords, and width and height) scrollPane.setBounds(195, 55, 230, 53); scrollPane.setVisible(true); } @@ -255,18 +202,14 @@ private void chunkAndCompressorProperties(){ model.addRow(data); chunkScrollPane = new JScrollPane(chunkTable); - // Original width = 210, height = 75 chunkScrollPane.setPreferredSize(new Dimension(200, 100)); // Actually setting how large the scroll pane is. - // chunkScrollPane.setBounds(170, 205, 255, 40); // Set where we want the JTable to be located in the JFrame. (This line is what updates the X, Y coordinates of widget) chunkScrollPane.setBounds(195, 125, 230, 53); // Set where we want the JTable to be located in the JFrame. (This line is what updates the X, Y coordinates of widget) chunkScrollPane.setVisible(true); - // Compressor = default is lz4 (though the user, should also be able to change the default as an option as well) compressorLabel.setText("Compressor: "); - compressorLabel.setBounds(180, 195, 130, 20); // NOTE: Higher the Y-axis lower widgets are positioned. Higher X axis, more to right the widgets positioned at. + compressorLabel.setBounds(180, 195, 130, 20); // NOTE FOR REF: Higher the Y-axis lower widgets are positioned. Higher X axis, more to right the widgets positioned at. compressTextArea.setText(compressor); - // compressTextArea.setBounds(265,245, 65, 19); compressTextArea.setBounds(265,195, 65, 19); } @@ -284,91 +227,71 @@ private void errorMessage(){ JOptionPane.showMessageDialog(window, message); } - // show function, has keeps track of all the added components into JFrame -> going to -> JPanel -> widgets/checkboxes/etc. + private void show(){ - // NOTE: Add to panel - // Adding/packing all widgets into the panel, then referring that panel to the window. - // This portion adds in the user input interface interaction widgets into there own panel. + // sets up text area box. textAreaPanel.add(textAreaLabel); textAreaPanel.add(textArea); textAreaPanel.add(browse); - textAreaPanel.setSize(50, 50); - // Adds the other widgets into the JFrame window themselves. + // sets up widgets to interface. window.add(startCoordsLabel); window.add(endCoordsLabel); window.add(scrollPane); window.add(chunkScrollPane); window.add(compressorLabel); window.add(compressTextArea); - - window.add(saveButton); - - // Setting window/jframe properties - // window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.add(textAreaPanel, BorderLayout.CENTER); // This is how the TextArea and Labels, are being centered to the TOP of the interface. + window.pack(); window.setLocation(new Point(900, 250)); // Hopefully puts the screen in the center of the monitor (vary depending on monitoring) window.setVisible(true); } - // Handling events happening with the interface. @Override public void actionPerformed(ActionEvent e){ - if(e.getSource() == browse) loadfile(); // We want to check if the checkbox is clicked before we compress that file. - // Updates and clears the table. - if(e.getSource() == saveButton) { - updateTable(); // Updates the table when we submit the changes, and then is the function that quits out the JFrame for this specific interface. - } + if(e.getSource() == browse) loadfile(); // We want to check if the checkbox is clicked before we compress that file. + if(e.getSource() == saveButton) update(); // Updates the changes to interface. + } - // Loading filepath given. + // Load new/selected file. private void loadfile(){ - // File Handling stuff. (Referenced PWZ.java) - // PWZC pwzc = new PWZC(); // This code is only used to call the C-functionality... (Wont work on mac, so comment out in the meantime.) JFileChooser chooser = new JFileChooser(); chooser.setApproveButtonText("Save"); chooser.setDialogTitle("Save as Zarr"); File file = null; - int returnValue = chooser.showOpenDialog(null); + int returnValue = chooser.showDialog(null, "Save"); if(returnValue == JFileChooser.APPROVE_OPTION) file = chooser.getSelectedFile(); + if(file == null) return; - ImagePlus cImagePlus = IJ.getImage(); - - if(cImagePlus == null) return; - this.filepath = file.getPath(); - - // pwzc.parallelWriteZarr(this.filepath, this.cImageObj, this.startX, this.startY, this.startZ, this.endX, this.endY, this.endZ, this.chunkSizeX, this.chunkSizeY, this.chunkSizeZ, 1, this.compressor, 1, this.bits); + textArea.setText(this.filepath); // updates text area. } + // Function for handling file extensions. private boolean checkExtension(String path){ String extension = ""; int i = path.lastIndexOf('.'); if(i != -1) extension = path.substring(i+1); - - // System.out.println("LOGGER: " + extension + ", i = " + i); // For debugging purposes. if(extension.equals("zarr")) return true; return false; } - // When "Save" button is clicked, updates interface. - private void updateTable(){ - - // Checks if text box is a .zarr file. If not show error msg. - if(!checkExtension(this.filepath) && !checkExtension(textArea.getText())) errorMessage(); - - textArea.setText(this.filepath); // updates text area. + // When "Save" is clicked then updates interface. + private void update(){ + if(!checkExtension(this.filepath) && !checkExtension(textArea.getText())) errorMessage(); // Checks if the file is a zarr file before we save and update + // Manually adding inputs into the charts. Maybe a better way, but for now. table.getModel().setValueAt(startX, 0, 0); table.getModel().setValueAt(startY, 0, 1); table.getModel().setValueAt(startZ, 0, 2); @@ -379,10 +302,5 @@ private void updateTable(){ chunkTable.getModel().setValueAt(chunkSizeX, 0, 0); chunkTable.getModel().setValueAt(chunkSizeY, 0, 1); chunkTable.getModel().setValueAt(chunkSizeZ, 0, 2); - - // window.dispose(); // Dispose() is how we will exit, once the submit changes have been made. } - - // For testing and debugging the interface with a main method. - // public static void main(String[] args) { new PWZGUI(); } } \ No newline at end of file From 4c8ad353fc429d814a15fb9f90147669c65f8b5a Mon Sep 17 00:00:00 2001 From: Matthew Mueller Date: Wed, 16 Nov 2022 01:58:09 -0800 Subject: [PATCH 06/10] Changed save button to just say "Save" --- .../src/main/java/edu/abc/berkeley/PWZGUI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java index cfde888..c893832 100644 --- a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java +++ b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java @@ -216,7 +216,7 @@ private void chunkAndCompressorProperties(){ // Function to help organize the widget that handles the saving changes button. // When browsing this save button will update the text box. private void save() { - saveButton = new JButton("Save Changes"); + saveButton = new JButton("Save"); saveButton.setBounds(175, 225, 115, 25); saveButton.addActionListener(this); } @@ -303,4 +303,4 @@ private void update(){ chunkTable.getModel().setValueAt(chunkSizeY, 0, 1); chunkTable.getModel().setValueAt(chunkSizeZ, 0, 2); } -} \ No newline at end of file +} From ff3be95cd073c99201a8ba088281da4fa8476d36 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Wed, 16 Nov 2022 02:18:04 -0800 Subject: [PATCH 07/10] Finalizing changes and refactored the save button. --- .../src/main/java/edu/abc/berkeley/PWZGUI.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java index c893832..e0d313c 100644 --- a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java +++ b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java @@ -50,7 +50,7 @@ public class PWZGUI implements ActionListener{ JTable chunkTable; // Table to show Chunk Size XYZ. (Changeable) JScrollPane chunkScrollPane; - JButton saveButton; // save changes + JButton save; // save changes public PWZGUI() { filepath = ""; @@ -216,9 +216,9 @@ private void chunkAndCompressorProperties(){ // Function to help organize the widget that handles the saving changes button. // When browsing this save button will update the text box. private void save() { - saveButton = new JButton("Save"); - saveButton.setBounds(175, 225, 115, 25); - saveButton.addActionListener(this); + save = new JButton("Save"); + save.setBounds(175, 225, 115, 25); + save.addActionListener(this); } // Display error message window, if the file is not a zarr file. @@ -242,7 +242,7 @@ private void show(){ window.add(chunkScrollPane); window.add(compressorLabel); window.add(compressTextArea); - window.add(saveButton); + window.add(save); window.add(textAreaPanel, BorderLayout.CENTER); // This is how the TextArea and Labels, are being centered to the TOP of the interface. window.pack(); @@ -254,7 +254,7 @@ private void show(){ public void actionPerformed(ActionEvent e){ if(e.getSource() == browse) loadfile(); // We want to check if the checkbox is clicked before we compress that file. - if(e.getSource() == saveButton) update(); // Updates the changes to interface. + if(e.getSource() == save) update(); // Updates the changes to interface. } From c7fe3f8e7c6f39be78b077616d76cbbeb8465784 Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Wed, 16 Nov 2022 14:22:22 -0800 Subject: [PATCH 08/10] Made some changes by refactoring the submit function --- .../main/java/edu/abc/berkeley/PWZGUI.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java index e0d313c..03fe866 100644 --- a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java +++ b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java @@ -254,7 +254,7 @@ private void show(){ public void actionPerformed(ActionEvent e){ if(e.getSource() == browse) loadfile(); // We want to check if the checkbox is clicked before we compress that file. - if(e.getSource() == save) update(); // Updates the changes to interface. + if(e.getSource() == save) submit(); // Updates the changes to interface. } @@ -287,20 +287,26 @@ private boolean checkExtension(String path){ return false; } - // When "Save" is clicked then updates interface. - private void update(){ + // "Submit" changes when "Save" clicked then updates interface. + private void submit(){ if(!checkExtension(this.filepath) && !checkExtension(textArea.getText())) errorMessage(); // Checks if the file is a zarr file before we save and update // Manually adding inputs into the charts. Maybe a better way, but for now. - table.getModel().setValueAt(startX, 0, 0); - table.getModel().setValueAt(startY, 0, 1); - table.getModel().setValueAt(startZ, 0, 2); - table.getModel().setValueAt(endX, 1, 0); - table.getModel().setValueAt(endY, 1, 1); - table.getModel().setValueAt(endZ, 1, 2); - - chunkTable.getModel().setValueAt(chunkSizeX, 0, 0); - chunkTable.getModel().setValueAt(chunkSizeY, 0, 1); - chunkTable.getModel().setValueAt(chunkSizeZ, 0, 2); + startX = (long) table.getModel().getValueAt(0, 0); + startY = (long) table.getModel().getValueAt(0, 1); + startZ = (long) table.getModel().getValueAt(0, 2); + endX = (long) table.getModel().getValueAt(1, 0); + endY = (long) table.getModel().getValueAt(1, 1); + endZ = (long) table.getModel().getValueAt(1, 2); + + chunkSizeX = (long) chunkTable.getModel().getValueAt(0, 0); + chunkSizeY = (long) chunkTable.getModel().getValueAt(0, 1); + chunkSizeZ = (long) chunkTable.getModel().getValueAt(0, 2); + + bits = imageStack.getBitDepth(); + + PWZC pwzc = new PWZC(); + + pwzc.parallelWriteZarr(filepath, cImageObj, startX, startY, startZ, endX, endY, endZ, chunkSizeX, chunkSizeY, chunkSizeZ, 1, compressor, 1, bits); } } From e01ad0498a7ffe18bed73789a825688ee587d4de Mon Sep 17 00:00:00 2001 From: = <=> Date: Sun, 18 Dec 2022 03:26:35 -0800 Subject: [PATCH 09/10] Refactored and allow widgets to be resizable and adjustable, and made layout changes to interface. --- .../main/java/edu/abc/berkeley/PWZGUI.java | 310 ++++++++++-------- 1 file changed, 171 insertions(+), 139 deletions(-) diff --git a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java index 03fe866..416ffdd 100644 --- a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java +++ b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java @@ -10,49 +10,50 @@ import java.io.File; -public class PWZGUI implements ActionListener{ - JFrame window; - JPanel textAreaPanel; - - JButton browse; // Browse specific files/folders. - - // Text box - JLabel textAreaLabel; - JTextArea textArea; - - // For compressor lz4 - JTextArea compressTextArea;// Compressor Text Area - JLabel compressorLabel; // Default Compressor - - +public class PWZGUI extends JFrame implements ActionListener{ + // Panel contains three fields. + // GroupLayout - Layout that groups these specific widgets together + // searchField - JTextField + // browse - JButton + // filepathLabel - JLabel + JPanel textfieldPanel; + GroupLayout textGroupLayout; // layout to group these widgets together + JTextField searchField; + JButton browse; + JButton save; + JLabel filepathLabel; + + // Setting up starting and ending coords JTable and JTablePanel. + JPanel coordsPanel; // panel containing JTable JTable table; JScrollPane scrollPane; - - JLabel startCoordsLabel; - JLabel endCoordsLabel; - - public String filepath; - public String compressor; // Starting and ending XYZ - public long startX=0, startY=0, startZ=0; - public long endX=0, endY=0, endZ=0; + public long startX, startY, startZ; + public long endX, endY, endZ; - // Default values for the chunk sizes. - public long chunkSizeX=256, chunkSizeY=256, chunkSizeZ=256; + // Chunk Table-related properties + JPanel chunkPanel; + JTable chunkTable; + JScrollPane chunkScrollPane; - public ImageStack imageStack; + public long chunkSizeX, chunkSizeY, chunkSizeZ; - public Object[] cImageObj; + // Compression labels and textFields and save JButton + JPanel compressorPanel; + GroupLayout compressorLayout; + JLabel compressorLabel; + JTextField compressorField; - public long bits; + String filepath; + String compressor; - JTable chunkTable; // Table to show Chunk Size XYZ. (Changeable) - JScrollPane chunkScrollPane; - - JButton save; // save changes + ImageStack imageStack; + Object[] cImageObj; + long bits; - public PWZGUI() { + + public PWZGUI(){ filepath = ""; compressor = "lz4"; // Default expected to be lz4. (Is changeable) imageStack = null; @@ -62,28 +63,13 @@ public PWZGUI() { endX = 0; endY = 0; endZ = 0; - - // These default values are for the chunk sizes. That should remain as the default. chunkSizeX = 256; chunkSizeY = 256; chunkSizeZ = 256; - bits = 0; - - // Creates a thread. Lets be called and execute object in its own instance. - // Basically like its own thread. - Runnable r = new Runnable() { - @Override - public void run(){ - init(); - } - }; - - // Swing GUIs should be created and updated on the EDT - // http://docs.oracle.com/javase/tutorial/uiswing/concurrency - SwingUtilities.invokeLater(r); + run(); } - + public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, long startZ, long endX, long endY, long endZ, long chunkSizeX, long chunkSizeY, long chunkSizeZ, String compressor, long bits){ this.filepath = filepath; this.compressor = compressor; @@ -105,6 +91,10 @@ public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, this.bits = bits; + run(); + } + + public void run(){ // Creates a thread. Lets be called and execute object in its own instance. // Basically like its own thread. Runnable r = new Runnable(){ @@ -116,52 +106,101 @@ public void run(){ SwingUtilities.invokeLater(r); } - + private void init(){ - window = new JFrame("Write Zarr"); - textAreaPanel = new JPanel(); // Main Panel - compressorLabel = new JLabel(); - compressTextArea = new JTextArea(); - - setupTextProperties(); // Handling button widget - grabCoordinates(); - chunkAndCompressorProperties(); - save(); // Save: What this does is submit the given changes, then close this specific interface. - show(); // Just adds in buttons to frame. - - window.setSize(600, 300); - window.setVisible(true); + setTitle("Write Zarr"); + setSize(800, 600); + + // Grab the primary monitor screen dimension + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + + // set the location of the frame to be in the center of the primary monitor + setLocation(screenSize.width/2 - getWidth()/2, screenSize.height/2 - getHeight()/2); + + filepathProperties(); + startingEndingCoords(); + chunkProperties(); + + pack(); } - // setting up text input properties. - private void setupTextProperties(){ + private void filepathProperties(){ + textfieldPanel = new JPanel(); + textGroupLayout = new GroupLayout(textfieldPanel); + textfieldPanel.setLayout(textGroupLayout); + + searchField = new JTextField(30); browse = new JButton("Browse"); - browse.setBounds(300, 5, 15, 15); + save = new JButton("Save"); + filepathLabel = new JLabel("Filepath"); + browse.addActionListener(this); + save.addActionListener(this); - // Handling text box and label - textAreaLabel = new JLabel("Filepath"); - textAreaLabel.setBounds(125, 5, 90, 15); + - textArea = new JTextArea(1, 6); - textArea.setBounds(215, 5, 75, 25); - textArea.setLayout(new FlowLayout()); + textGroupLayout.setAutoCreateGaps(true); + textGroupLayout.setAutoCreateContainerGaps(true); + + // Handles horizontally aligning are widgets and set the JPanel using GroupLayout to BorderLayout.NORTH + // sets the components grouped up together in the order we want them to be layed out. + textGroupLayout.setHorizontalGroup(textGroupLayout.createSequentialGroup() + .addComponent(filepathLabel) + .addComponent(searchField) + .addComponent(browse) + .addComponent(save) + ); + + // Handles vertically aligning are widgets and set the JPanel using GroupLayout to BorderLayout.NORTH + textGroupLayout.setVerticalGroup(textGroupLayout.createParallelGroup() + .addComponent(filepathLabel) + .addComponent(searchField) + .addComponent(browse) + .addComponent(save) + ); + + getContentPane().add(textfieldPanel, BorderLayout.NORTH); } - - private void grabCoordinates(){ - // Labels allowing the user using the interface to know - startCoordsLabel = new JLabel("Start"); - endCoordsLabel = new JLabel("End"); - startCoordsLabel.setBounds(140, 5, 150, 150); - endCoordsLabel.setBounds(145, 20, 150, 150); + private void startingEndingCoords(){ + coordsPanel = new JPanel(new GridBagLayout()); + scrollPane = new JScrollPane(); + table = new JTable(10, 10); - Object[][] data = { - {startX, startY, startZ}, - {endX, endY, endZ}, - }; + GridBagConstraints gbc = new GridBagConstraints(); + gbc.weightx = 1.0; + gbc.gridheight = 50; + gbc.gridwidth = 100; + gbc.fill = GridBagConstraints.HORIZONTAL; // This fills the interface with horizontally. Uncomment to see changes. + + updateTable(); + + coordsPanel.add(scrollPane, gbc); + + add(coordsPanel, BorderLayout.CENTER); + } + + private void chunkProperties(){ + chunkPanel = new JPanel(); + chunkPanel.setLayout(new BorderLayout()); + + compressorPanel = new JPanel(); + compressorLayout = new GroupLayout(compressorPanel); + compressorPanel.setLayout(compressorLayout); + + compressorLabel = new JLabel("Compressor"); + compressorField = new JTextField(compressor); + + chunkData(); + compressorLayoutProperties(); + chunkPanel.add(compressorPanel, BorderLayout.SOUTH); + add(chunkPanel, BorderLayout.SOUTH); + } + + + public void updateTable(){ DefaultTableModel tableModel = new DefaultTableModel(){ @Override public boolean isCellEditable(int row, int col) { @@ -173,13 +212,20 @@ public boolean isCellEditable(int row, int col) { table = new JTable(tableModel); table.setBounds(235, 55, 115, 25); + Object[][] data1 = {{startX, startY, startZ, endX, endY, endZ}}; + // Adding columns to the table - tableModel.addColumn("X"); - tableModel.addColumn("Y"); - tableModel.addColumn("Z"); + tableModel.addColumn("Start X"); + tableModel.addColumn("Start Y"); + tableModel.addColumn("Start Z"); + tableModel.addColumn("End X"); + tableModel.addColumn("End Y"); + tableModel.addColumn("End Z"); + // Adding rows to the table. - for(int i = 0; i < data.length; i++) tableModel.addRow(data[i]); + for(int i = 0; i < data1.length; i++) tableModel.addRow(data1[i]); + scrollPane = new JScrollPane(table); scrollPane.setPreferredSize(new Dimension(250, 100)); // Actually setting how large the scroll pane is. @@ -187,7 +233,7 @@ public boolean isCellEditable(int row, int col) { scrollPane.setVisible(true); } - private void chunkAndCompressorProperties(){ + private void chunkData(){ // Setting up JTable specifically for Chunk Size. Object[] data = {chunkSizeX, chunkSizeY, chunkSizeZ}; DefaultTableModel model = new DefaultTableModel(); @@ -202,60 +248,38 @@ private void chunkAndCompressorProperties(){ model.addRow(data); chunkScrollPane = new JScrollPane(chunkTable); - chunkScrollPane.setPreferredSize(new Dimension(200, 100)); // Actually setting how large the scroll pane is. - chunkScrollPane.setBounds(195, 125, 230, 53); // Set where we want the JTable to be located in the JFrame. (This line is what updates the X, Y coordinates of widget) - chunkScrollPane.setVisible(true); - - compressorLabel.setText("Compressor: "); - compressorLabel.setBounds(180, 195, 130, 20); // NOTE FOR REF: Higher the Y-axis lower widgets are positioned. Higher X axis, more to right the widgets positioned at. - - compressTextArea.setText(compressor); - compressTextArea.setBounds(265,195, 65, 19); + chunkScrollPane.setPreferredSize(new Dimension(20, 90)); + chunkScrollPane.setLocation(200, 250); } - // Function to help organize the widget that handles the saving changes button. - // When browsing this save button will update the text box. - private void save() { - save = new JButton("Save"); - save.setBounds(175, 225, 115, 25); - save.addActionListener(this); + private void compressorLayoutProperties(){ + compressorLayout.setAutoCreateGaps(true); + compressorLayout.setAutoCreateContainerGaps(true); + + // Handling vertical and horizontally alignments in the windodw. + //horizontal alignment + compressorLayout.setHorizontalGroup( + compressorLayout.createSequentialGroup() + .addComponent(chunkScrollPane) + .addComponent(compressorLabel) + .addComponent(compressorField) + ); + + //vertical alignment + compressorLayout.setVerticalGroup( + compressorLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(chunkScrollPane) + .addGap(20) + .addComponent(compressorLabel) + .addComponent(compressorField) + ); } // Display error message window, if the file is not a zarr file. private void errorMessage(){ String message = "File must be a zarr file"; - JOptionPane.showMessageDialog(window, message); - } - - - private void show(){ - // sets up text area box. - textAreaPanel.add(textAreaLabel); - textAreaPanel.add(textArea); - textAreaPanel.add(browse); - textAreaPanel.setSize(50, 50); - - // sets up widgets to interface. - window.add(startCoordsLabel); - window.add(endCoordsLabel); - window.add(scrollPane); - window.add(chunkScrollPane); - window.add(compressorLabel); - window.add(compressTextArea); - window.add(save); - window.add(textAreaPanel, BorderLayout.CENTER); // This is how the TextArea and Labels, are being centered to the TOP of the interface. - - window.pack(); - window.setLocation(new Point(900, 250)); // Hopefully puts the screen in the center of the monitor (vary depending on monitoring) - window.setVisible(true); - } - - @Override - public void actionPerformed(ActionEvent e){ - - if(e.getSource() == browse) loadfile(); // We want to check if the checkbox is clicked before we compress that file. - if(e.getSource() == save) submit(); // Updates the changes to interface. - + JOptionPane.showMessageDialog(this, message); + return; } // Load new/selected file. @@ -266,13 +290,12 @@ private void loadfile(){ File file = null; int returnValue = chooser.showDialog(null, "Save"); - if(returnValue == JFileChooser.APPROVE_OPTION) file = chooser.getSelectedFile(); if(file == null) return; this.filepath = file.getPath(); - textArea.setText(this.filepath); // updates text area. + searchField.setText(this.filepath); // updates text area. } // Function for handling file extensions. @@ -289,7 +312,10 @@ private boolean checkExtension(String path){ // "Submit" changes when "Save" clicked then updates interface. private void submit(){ - if(!checkExtension(this.filepath) && !checkExtension(textArea.getText())) errorMessage(); // Checks if the file is a zarr file before we save and update + if(!checkExtension(this.filepath) && !checkExtension(searchField.getText())) { + errorMessage(); // Checks if the file is a zarr file before we save and update + return; // Do not want to continue so leave function. (OutofBounds error will occur, if this does not leave function call) + } // Manually adding inputs into the charts. Maybe a better way, but for now. startX = (long) table.getModel().getValueAt(0, 0); @@ -309,4 +335,10 @@ private void submit(){ pwzc.parallelWriteZarr(filepath, cImageObj, startX, startY, startZ, endX, endY, endZ, chunkSizeX, chunkSizeY, chunkSizeZ, 1, compressor, 1, bits); } + + @Override + public void actionPerformed(ActionEvent e){ + if(e.getSource() == browse) loadfile(); // We want to check if the checkbox is clicked before we compress that file. + if(e.getSource() == save) submit(); // Updates the changes to interface. + } } From 972c8730a3086c0244b7f3ca5b3124a1cac3ac7c Mon Sep 17 00:00:00 2001 From: SpinnerX Date: Fri, 6 Jan 2023 19:22:57 -0800 Subject: [PATCH 10/10] Added dropdown menu feature to show compression options --- .../main/java/edu/abc/berkeley/PWZGUI.java | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java index 416ffdd..a22f2cf 100644 --- a/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java +++ b/Parallel_Fiji_Visualizer/src/main/java/edu/abc/berkeley/PWZGUI.java @@ -11,11 +11,13 @@ import java.io.File; public class PWZGUI extends JFrame implements ActionListener{ - // Panel contains three fields. - // GroupLayout - Layout that groups these specific widgets together - // searchField - JTextField - // browse - JButton - // filepathLabel - JLabel + /* + Panel contains three fields. + GroupLayout - Layout that groups these specific widgets together + searchField - JTextField + browse - JButton + filepathLabel - JLabel + */ JPanel textfieldPanel; GroupLayout textGroupLayout; // layout to group these widgets together JTextField searchField; @@ -43,7 +45,7 @@ public class PWZGUI extends JFrame implements ActionListener{ JPanel compressorPanel; GroupLayout compressorLayout; JLabel compressorLabel; - JTextField compressorField; + JComboBox compressorComboBox; String filepath; String compressor; @@ -55,7 +57,7 @@ public class PWZGUI extends JFrame implements ActionListener{ public PWZGUI(){ filepath = ""; - compressor = "lz4"; // Default expected to be lz4. (Is changeable) + compressor = "lz4"; // Default expected to be lz4. (Can be modiefied) imageStack = null; startX = 0; startY = 0; @@ -67,7 +69,7 @@ public PWZGUI(){ chunkSizeY = 256; chunkSizeZ = 256; - run(); + initialize(); } public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, long startZ, long endX, long endY, long endZ, long chunkSizeX, long chunkSizeY, long chunkSizeZ, String compressor, long bits){ @@ -91,23 +93,25 @@ public PWZGUI(String filepath, ImageStack imageStack, long startX, long startY, this.bits = bits; - run(); + initialize(); } - public void run(){ + // This helps us create one instance to run the interface and call in each of the constructor + // Rather then having the same runnable in both, we create a function to call once to initialize the itnerface + public void initialize(){ // Creates a thread. Lets be called and execute object in its own instance. // Basically like its own thread. Runnable r = new Runnable(){ @Override public void run(){ - init(); + setup(); } }; SwingUtilities.invokeLater(r); } - private void init(){ + private void setup(){ setTitle("Write Zarr"); setSize(800, 600); @@ -137,9 +141,6 @@ private void filepathProperties(){ browse.addActionListener(this); save.addActionListener(this); - - - textGroupLayout.setAutoCreateGaps(true); textGroupLayout.setAutoCreateContainerGaps(true); @@ -174,7 +175,7 @@ private void startingEndingCoords(){ gbc.gridwidth = 100; gbc.fill = GridBagConstraints.HORIZONTAL; // This fills the interface with horizontally. Uncomment to see changes. - updateTable(); + update(); // update table coordsPanel.add(scrollPane, gbc); @@ -190,7 +191,9 @@ private void chunkProperties(){ compressorPanel.setLayout(compressorLayout); compressorLabel = new JLabel("Compressor"); - compressorField = new JTextField(compressor); + + String[] options = {"lz4", "zstd", "blosclz", "lz4hc", "zlib", "gzip"}; // dropdown menu options important to less important + compressorComboBox = new JComboBox(options); chunkData(); compressorLayoutProperties(); @@ -200,7 +203,8 @@ private void chunkProperties(){ } - public void updateTable(){ + // Update table + public void update(){ DefaultTableModel tableModel = new DefaultTableModel(){ @Override public boolean isCellEditable(int row, int col) { @@ -256,13 +260,14 @@ private void compressorLayoutProperties(){ compressorLayout.setAutoCreateGaps(true); compressorLayout.setAutoCreateContainerGaps(true); + // Handling vertical and horizontally alignments in the windodw. //horizontal alignment compressorLayout.setHorizontalGroup( compressorLayout.createSequentialGroup() .addComponent(chunkScrollPane) .addComponent(compressorLabel) - .addComponent(compressorField) + .addComponent(compressorComboBox) ); //vertical alignment @@ -271,7 +276,7 @@ private void compressorLayoutProperties(){ .addComponent(chunkScrollPane) .addGap(20) .addComponent(compressorLabel) - .addComponent(compressorField) + .addComponent(compressorComboBox) // dropdown menu with options ); } @@ -298,7 +303,7 @@ private void loadfile(){ searchField.setText(this.filepath); // updates text area. } - // Function for handling file extensions. + // helper function to check if file extension has .zarr private boolean checkExtension(String path){ String extension = ""; int i = path.lastIndexOf('.');