Skip to content

Commit

Permalink
Some features (#33)
Browse files Browse the repository at this point in the history
* Add line number for text editor using TextLineNumber;
Fix scroll issue

* Add remove segment button
  • Loading branch information
zehuanncc authored Feb 26, 2020
1 parent a25dfe2 commit ca94880
Show file tree
Hide file tree
Showing 5 changed files with 543 additions and 25 deletions.
3 changes: 2 additions & 1 deletion src/main/trust/nccgroup/decoderimproved/CONSTANTS.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ public class CONSTANTS {
public static final int COMBO_BOX_SHORT_WIDTH = 70;
public static final int COMBO_BOX_HEIGHT = 25;
public static final int INPUT_BOX_HEIGHT = 30;
public static final int SEGMENT_HEIGHT = 205;
public static final int SEGMENT_HEIGHT = 215;
public static final int PANEL_HEIGHT = 200;

public static Dimension COMBO_BOX_DIMENSION = new Dimension(CONSTANTS.COMBO_BOX_WIDTH, CONSTANTS.COMBO_BOX_HEIGHT);

public static Font SMALLER_FONT = new JLabel().getFont().deriveFont((float) new JLabel().getFont().getSize() * 3 / 4);
public static Font SMALLEST_FONT = new JLabel().getFont().deriveFont((float) new JLabel().getFont().getSize() * 1 / 4);

public static final int META_MASK = java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import trust.nccgroup.decoderimproved.modes.AbstractModificationMode;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.PopupMenuEvent;
Expand All @@ -30,12 +31,13 @@ public class DecoderSegment extends JPanel {

public DecoderSegmentState dsState;

private JPanel radioPanel;
private JPanel segmentControlPanel;

// This changes the editor between hex view and text view
private ButtonGroup textHexGroup;
private JRadioButton textRadio;
public JRadioButton hexRadio;
private JButton closeButton;
private JPanel textControlPanel;
private JLabel textInfoLabel;
private JCheckBox textWrapCheckBox;
Expand Down Expand Up @@ -163,10 +165,11 @@ private void setupComponents() {
editorPanel = new PDControlScrollPane();
hexPanel = new JScrollPane();
controlPanel = new JPanel();
radioPanel = new JPanel();
segmentControlPanel = new JPanel();
textRadio = new JRadioButton();
hexRadio = new JRadioButton();
textControlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
closeButton = new JButton();
textControlPanel = new JPanel();
textInfoLabel = new JLabel();
textWrapCheckBox = new JCheckBox();
exportComboBox = new JComboBox<>();
Expand All @@ -181,7 +184,7 @@ private void setupComponents() {
this.setMaximumSize(new Dimension(3000, CONSTANTS.SEGMENT_HEIGHT));
this.setMinimumSize(new Dimension(50, CONSTANTS.SEGMENT_HEIGHT));
this.setPreferredSize(new Dimension(711, CONSTANTS.SEGMENT_HEIGHT));
this.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0));
this.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 0));
this.setLayout(new GridBagLayout());

editorPanel.setMinimumSize(new Dimension(50, CONSTANTS.PANEL_HEIGHT));
Expand All @@ -199,25 +202,31 @@ private void setupComponents() {

hexPanel.setViewportView(hexEditor);
editorPanel.setViewportView(textEditor);
// Use TextLineNumber for line number display
TextLineNumber tln = new TextLineNumber(textEditor);
tln.setUpdateFont(true);
tln.setMinimumDisplayDigits(1);
editorPanel.setRowHeaderView(tln);

masterEditorPanel.add(editorPanel);
masterEditorPanel.add(hexPanel);

GridBagConstraints editorPanelConstraints = new GridBagConstraints();
editorPanelConstraints.fill = GridBagConstraints.HORIZONTAL;
editorPanelConstraints.anchor = GridBagConstraints.WEST;
editorPanelConstraints.weightx = 1.0;

masterEditorPanel.add(editorPanel);
masterEditorPanel.add(hexPanel);

this.add(masterEditorPanel, editorPanelConstraints);
controlPanel.setMaximumSize(new Dimension(150, CONSTANTS.PANEL_HEIGHT));
controlPanel.setMinimumSize(new Dimension(150, CONSTANTS.PANEL_HEIGHT));
controlPanel.setPreferredSize(new Dimension(150, CONSTANTS.PANEL_HEIGHT));
controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.PAGE_AXIS));

// Radio group
radioPanel.setMaximumSize(new Dimension(125, CONSTANTS.COMBO_BOX_HEIGHT));
radioPanel.setMinimumSize(new Dimension(125, CONSTANTS.COMBO_BOX_HEIGHT));
radioPanel.setPreferredSize(new Dimension(125, CONSTANTS.COMBO_BOX_HEIGHT));
radioPanel.setLayout(new GridLayout());
segmentControlPanel.setMaximumSize(new Dimension(CONSTANTS.COMBO_BOX_WIDTH, CONSTANTS.COMBO_BOX_HEIGHT));
segmentControlPanel.setMinimumSize(new Dimension(CONSTANTS.COMBO_BOX_WIDTH, CONSTANTS.COMBO_BOX_HEIGHT));
segmentControlPanel.setPreferredSize(new Dimension(CONSTANTS.COMBO_BOX_WIDTH, CONSTANTS.COMBO_BOX_HEIGHT));
segmentControlPanel.setLayout(new FlowLayout());

textRadio.setText("Text");
textRadio.setSelected(true);
Expand All @@ -230,10 +239,20 @@ private void setupComponents() {

textHexGroup.add(textRadio);
textHexGroup.add(hexRadio);
segmentControlPanel.add(textRadio);
segmentControlPanel.add(hexRadio);

// Add close button if the segment is not the first one in a tab
closeButton.setText("✕");
closeButton.setFont(new Font("monospaced", Font.PLAIN, 10));
closeButton.setBorder(new EmptyBorder(0, 0, 0, 0));
closeButton.setMaximumSize(new Dimension(20, 20));
closeButton.setMinimumSize(new Dimension(20, 20));
closeButton.setPreferredSize(new Dimension(20, 20));
segmentControlPanel.add(Box.createRigidArea(new Dimension(10, 0)));
segmentControlPanel.add(closeButton);

radioPanel.add(textRadio);
radioPanel.add(hexRadio);
controlPanel.add(radioPanel);
controlPanel.add(segmentControlPanel);

// Modes
controlPanel.add(modeManager.getUI());
Expand All @@ -250,6 +269,7 @@ private void setupComponents() {
textControlPanel.setMaximumSize(CONSTANTS.COMBO_BOX_DIMENSION);
textControlPanel.setMinimumSize(CONSTANTS.COMBO_BOX_DIMENSION);
textControlPanel.setPreferredSize(CONSTANTS.COMBO_BOX_DIMENSION);
textControlPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));

textInfoLabel.setMaximumSize(new Dimension(CONSTANTS.COMBO_BOX_SHORT_WIDTH, CONSTANTS.COMBO_BOX_HEIGHT));
textInfoLabel.setMinimumSize(new Dimension(CONSTANTS.COMBO_BOX_SHORT_WIDTH, CONSTANTS.COMBO_BOX_HEIGHT));
Expand Down Expand Up @@ -288,6 +308,13 @@ private void setupComponents() {
cardManager.first(masterEditorPanel);
});

closeButton.addActionListener((ActionEvent e) -> {
if(JOptionPane.showConfirmDialog(this, "Delete this segment?", null, JOptionPane.YES_NO_OPTION)
== JOptionPane.YES_OPTION){
decoderTab.removeDecoderSegment(this);
}
});

exportComboBox.addActionListener((ActionEvent event) -> {
if (exportComboBox.getSelectedIndex() == 0) {
return;
Expand Down
15 changes: 13 additions & 2 deletions src/main/trust/nccgroup/decoderimproved/components/DecoderTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,25 @@ private void setupComponents() {

void addDecoderSegment() {
DecoderSegment ds = new DecoderSegment(this);
decoderTabBody.add(Box.createRigidArea(new Dimension(0, 10)));
//decoderTabBody.add(Box.createRigidArea(new Dimension(0, 10)));
decoderSegments.add(ds);
decoderTabBody.add(ds);

// Update last segment (based on second last segment)
updateNextDecoderSegment(decoderSegments.size() - 2);
}

void removeDecoderSegment(DecoderSegment decoderSegment) {
decoderTabBody.remove(decoderSegment);
decoderSegments.remove(decoderSegment);
if (decoderSegments.size() == 0) {
addDecoderSegment();
}
mainTab.repaint();
updateDecoderSegments(0, false);
decoderSegment.dsState.clear();
}

void updateDecoderSegments(int activeDecoderSegmentIndex, boolean addSegment) {
if (addSegment && activeDecoderSegmentIndex == decoderSegments.size() - 1) {
addDecoderSegment();
Expand All @@ -91,7 +102,7 @@ void updateDecoderSegments(int activeDecoderSegmentIndex, boolean addSegment) {
private void updateNextDecoderSegment(int activeDecoderSegmentIndex) {
// If the item is at the end of the list there isn't anything to update
// i.e. this prevents an array out of bounds error
if (activeDecoderSegmentIndex >= decoderSegments.size() - 1) {
if (activeDecoderSegmentIndex < 0 || activeDecoderSegmentIndex >= decoderSegments.size() - 1) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

//From http://stackoverflow.com/questions/1377887/jtextpane-prevents-scrolling-in-the-parent-jscrollpane/1379695#1379695
// Originally from http://stackoverflow.com/questions/1377887/jtextpane-prevents-scrolling-in-the-parent-jscrollpane/1379695#1379695

/**
* A JScrollPane that will bubble a mouse wheel scroll event to the parent
Expand All @@ -21,8 +21,10 @@ class PDControlScrollPane extends JScrollPane {

class PDMouseWheelListener implements MouseWheelListener {

private JScrollBar bar;
private int previousValue = 0;
private JScrollBar horizontalBar;
private JScrollBar verticalBar;
private int horizontalPreviousValue = 0;
private int verticalPreviousValue = 0;
private JScrollPane parentScrollPane;

private JScrollPane getParentScrollPane() {
Expand All @@ -37,7 +39,8 @@ private JScrollPane getParentScrollPane() {
}

PDMouseWheelListener() {
bar = PDControlScrollPane.this.getVerticalScrollBar();
horizontalBar = PDControlScrollPane.this.getHorizontalScrollBar();
verticalBar = PDControlScrollPane.this.getVerticalScrollBar();
}

@Override
Expand All @@ -48,15 +51,27 @@ public void mouseWheelMoved(MouseWheelEvent e) {
* Only dispatch if we have reached top/bottom on previous scroll
*/
if (e.getWheelRotation() < 0) {
if (bar.getValue() == 0 && previousValue == 0) {
// If vertical scroll bar exists
if (getMax(verticalBar) > 0) {
if (verticalBar.getValue() == 0 && verticalPreviousValue == 0) {
parent.dispatchEvent(cloneEvent(e));
}
} else if (horizontalBar.getValue() == 0 && horizontalPreviousValue == 0) {
parent.dispatchEvent(cloneEvent(e));
}

} else {
if (bar.getValue() == getMax() && previousValue == getMax()) {
// If vertical scroll bar exists
if (getMax(verticalBar) > 0) {
if (verticalBar.getValue() == getMax(verticalBar) && verticalPreviousValue == getMax(verticalBar)) {
parent.dispatchEvent(cloneEvent(e));
}
} else if (horizontalBar.getValue() == getMax(horizontalBar) && horizontalPreviousValue == getMax(horizontalBar)) {
parent.dispatchEvent(cloneEvent(e));
}
}
previousValue = bar.getValue();
horizontalPreviousValue = horizontalBar.getValue();
verticalPreviousValue = verticalBar.getValue();
}
/*
* If parent scrollpane doesn't exist, remove this as a listener.
Expand All @@ -68,7 +83,7 @@ public void mouseWheelMoved(MouseWheelEvent e) {
}
}

private int getMax() {
private int getMax(JScrollBar bar) {
return bar.getMaximum() - bar.getVisibleAmount();
}

Expand Down
Loading

0 comments on commit ca94880

Please sign in to comment.