/*
* Copyright (c) 2008-2019 Emmanuel Dupuy.
* This project is distributed under the GPLv3 license.
* This is a Copyleft license that gives the user the right to use,
* copy and modify the code freely for non-commercial purposes.
*/
package org.jd.gui.view;
import org.jd.gui.api.feature.LineNumberNavigable;
import org.jd.gui.model.configuration.Configuration;
import org.jd.gui.util.swing.SwingUtil;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.function.IntConsumer;
public class GoToView {
protected JDialog goToDialog;
protected JLabel goToEnterLineNumberLabel;
protected JTextField goToEnterLineNumberTextField;
protected JLabel goToEnterLineNumberErrorLabel;
protected LineNumberNavigable navigator;
protected IntConsumer okCallback;
public GoToView(Configuration configuration, JFrame mainFrame) {
// Build GUI
SwingUtil.invokeLater(() -> {
goToDialog = new JDialog(mainFrame, "Go to Line", false);
goToDialog.setResizable(false);
Box vbox = Box.createVerticalBox();
vbox.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
goToDialog.add(vbox);
// First label "Enter line number (1..xxx):"
Box hbox = Box.createHorizontalBox();
hbox.add(goToEnterLineNumberLabel = new JLabel());
hbox.add(Box.createHorizontalGlue());
vbox.add(hbox);
vbox.add(Box.createVerticalStrut(10));
// Text field
vbox.add(goToEnterLineNumberTextField = new JTextField(30));
vbox.add(Box.createVerticalStrut(10));
// Error label
hbox = Box.createHorizontalBox();
hbox.add(goToEnterLineNumberErrorLabel = new JLabel(" "));
goToEnterLineNumberTextField.addKeyListener(new KeyAdapter() {
@Override public void keyTyped(KeyEvent e) {
if (! Character.isDigit(e.getKeyChar())) {
e.consume();
}
}
});
hbox.add(Box.createHorizontalGlue());
vbox.add(hbox);
vbox.add(Box.createVerticalStrut(15));
// Buttons "Ok" and "Cancel"
hbox = Box.createHorizontalBox();
hbox.add(Box.createHorizontalGlue());
JButton goToOkButton = new JButton(" Ok ");
hbox.add(goToOkButton);
goToOkButton.setEnabled(false);
goToOkButton.addActionListener(e -> {
okCallback.accept(Integer.valueOf(goToEnterLineNumberTextField.getText()));
goToDialog.setVisible(false);
});
hbox.add(Box.createHorizontalStrut(5));
JButton goToCancelButton = new JButton("Cancel");
hbox.add(goToCancelButton);
Action goToCancelActionListener = new AbstractAction() {
public void actionPerformed(ActionEvent actionEvent) { goToDialog.setVisible(false); }
};
goToCancelButton.addActionListener(goToCancelActionListener);
vbox.add(hbox);
vbox.add(Box.createVerticalStrut(13));
// Last setup
JRootPane rootPane = goToDialog.getRootPane();
rootPane.setDefaultButton(goToOkButton);
rootPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "OpenTypeView.cancel");
rootPane.getActionMap().put("OpenTypeView.cancel", goToCancelActionListener);
// Add main listener
goToEnterLineNumberTextField.getDocument().addDocumentListener(new DocumentListener() {
protected Color backgroundColor = UIManager.getColor("TextField.background");
protected Color errorBackgroundColor = Color.decode(configuration.getPreferences().get("JdGuiPreferences.errorBackgroundColor"));
@Override public void insertUpdate(DocumentEvent e) { onTextChange(); }
@Override public void removeUpdate(DocumentEvent e) { onTextChange(); }
@Override public void changedUpdate(DocumentEvent e) { onTextChange(); }
protected void onTextChange() {
String text = goToEnterLineNumberTextField.getText();
if (text.length() == 0) {
goToOkButton.setEnabled(false);
clearErrorMessage();
} else {
try {
int lineNumber = Integer.valueOf(text);
if (lineNumber > navigator.getMaximumLineNumber()) {
goToOkButton.setEnabled(false);
showErrorMessage("Line number out of range");
} else if (navigator.checkLineNumber(lineNumber)) {
goToOkButton.setEnabled(true);
clearErrorMessage();
} else {
goToOkButton.setEnabled(false);
showErrorMessage("Line number not found");
}
} catch (NumberFormatException e) {
goToOkButton.setEnabled(false);
showErrorMessage("Not a number");
}
}
}
protected void showErrorMessage(String message) {
goToEnterLineNumberErrorLabel.setText(message);
goToEnterLineNumberTextField.setBackground(errorBackgroundColor);
}
protected void clearErrorMessage() {
goToEnterLineNumberErrorLabel.setText(" ");
goToEnterLineNumberTextField.setBackground(backgroundColor);
}
});
// Prepare to display
goToDialog.pack();
goToDialog.setLocationRelativeTo(mainFrame);
});
}
public void show(LineNumberNavigable navigator, IntConsumer okCallback) {
this.navigator = navigator;
this.okCallback = okCallback;
SwingUtil.invokeLater(() -> {
// Init
goToEnterLineNumberLabel.setText("Enter line number (1.." + navigator.getMaximumLineNumber() + "):");
goToEnterLineNumberTextField.setText("");
// Show
goToDialog.setVisible(true);
goToEnterLineNumberTextField.requestFocus();
});
}
}