📄 selectablereadinglist.java
字号:
//Title: Your Product Name
//Version:
//Copyright: Copyright (c) 1999
//Author: Doug Given
//Company: USGS
//Description: Your description
package org.trinet.jiggle;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.border.*;
import org.trinet.jasi.*;
import org.trinet.jasi.coda.*;
import org.trinet.util.*;
import org.trinet.util.graphics.ColorList;
/**
* A text JList of JasiReadings (Phase, Amp, Coda) that is selectable so that by
* clicking on a text line the channel is selected via the MasterView's masterWFWindowModel.
*
* This component does NOT listen to the masterWFWindowModel itself, :. doesn't
* change selection to match selections made in other views.
*/
public class SelectableReadingList extends JPanel {
Solution sol = null;
JasiReadingList readingList;
/** The subset of readingList that is visible. Virtually deleted events should not
* be shown. */
JasiReadingList visibleList;
String header = "";
JasiReadingListListener jasiReadingListListener = new JasiReadingListListener();
JButton recalcButton;
/** Optional actionListener that recalculates the summary value for these readings. */
ActionListener recalcListener;
// MasterView is needed for the models
MasterView mv;
BorderLayout borderLayout1 = new BorderLayout();
BorderLayout borderLayout2 = new BorderLayout();
JPanel topPanel = new JPanel();
JTextArea summaryTextArea = new JTextArea();
JScrollPane scroller = new JScrollPane();
JList jlist = new JList();
// flag to know if a popup is available
// boolean hasPopup = false;
// type of list we are showing
int type;
public static final int Phases = 0;
public static final int Amps = 1;
public static final int Codas = 2;
// type face size
Font font = new Font("Monospaced", Font.PLAIN, 12);
Font fontBold = new Font("Monospaced", Font.BOLD, 12);
Color summaryBackground = Color.yellow;
Color headerBackground = Color.gray;
Color selectedBackgroundColor = Color.lightGray;
public SelectableReadingList() {
try {
jbInit();
}
catch(Exception ex) {
ex.printStackTrace();
}
this.setFont(font);
jlist.setFont(font);
jlist.setCellRenderer(new SelectableListCellRenderer());
jlist.setModel(new DefaultListModel());
// jlist.setSelectionBackground(jlist.getBackground()); // white??
jlist.setSelectionBackground(selectedBackgroundColor);
// add listener to the JList (rather than the model)
jlist.addListSelectionListener(new SelectionListener());
summaryTextArea.setFont(fontBold);
summaryTextArea.setLineWrap(true);
summaryTextArea.setBackground(summaryBackground);
summaryTextArea.setEditable(false);
summaryTextArea.setBorder(BorderFactory.createRaisedBevelBorder());
}
/** Using 'type', construct the approriate type of reading component. */
public SelectableReadingList(MasterView mv, Solution solution, int type) {
this();
this.type = type;
this.mv = mv;
JasiReadingList readings;
if (type == Phases) {
readings = solution.phaseList;
} else if (type == Amps) {
readings = solution.ampList;
} else if (type == Codas){
readings = solution.codaList;
} else {
return;
}
setHeader(type);
setSolution(solution, type);
setReadingList(readings); // do first so we can tell if phases, amp, or codas
setSelectedFromWFViewModel();
}
public SelectableReadingList(MasterView mv,
Solution solution,
JasiReadingList readings) {
this();
this.mv = mv;
if (readings instanceof PhaseList) {
type = Phases;
} else if (readings instanceof AmpList) {
type = Amps;
} else if (readings instanceof CodaList) {
type = Codas;
}
setHeader(type);
setSolution(solution, type);
setReadingList(readings); // do first so we can tell if phases, amp, or codas
setSelectedFromWFViewModel();
}
/** Set the reading list header to the right type. */
protected void setHeader (int type) {
if (type == Phases) {
header = Phase.getNeatStringHeader();
} else if (type == Amps) {
header = Amplitude.getNeatStringHeader();
} else if (type == Codas){
header = Coda.getNeatStringHeader();
} else {
return;
}
}
public void setSolution(Solution solution, int type) {
sol = solution;
if (sol == null) {
summaryTextArea.setText(""); // clear any old stuff
} else {
String str = "";
// show summary location
if (type == Phases) {
str += sol.toNeatString() +
"\n" + sol.getErrorStringHeader() +
"\n" + sol.toErrorString();
// show summary mag
} else { // must be amps or codas
str += sol.magnitude.getNeatStringHeader() +
"\n" + sol.magnitude.toNeatString();
}
summaryTextArea.setText(str);
}
}
public void setReadingList (JasiReadingList list) {
if (list != null) {
if (readingList != list) { // a change
// remove listener from old list so reference doesn't dangle
if (readingList != null)
readingList.removeChangeListener(jasiReadingListListener);
readingList = list;
// add THIS as a listener to the new list
readingList.addChangeListener(jasiReadingListListener);
}
//readingList.timeSort(); // sort readings by time
readingList.distanceSort(sol.getLatLonZ());
// set the column header to the neatHeader
JLabel hLabel = new JLabel(header);
hLabel.setFont(getFont());
scroller.setColumnHeaderView(hLabel);
// filter out unassoc or deleted readings
visibleList = readingList.getAssociatedWithSol(sol);
jlist.setListData(visibleList.toArray());
}
}
public void setSelectedFromWFViewModel() {
// get selected channel from master model
if (mv != null && mv.masterWFViewModel.get() != null) {
Channel selChan = mv.masterWFViewModel.get().getChannelObj();
// will find *1st* occurance of Chan in the JList
int newIndex = visibleList.getIndexOf(selChan);
if (newIndex > 0 && newIndex < (jlist.getModel().getSize()-1))
jlist.setSelectedIndex(newIndex);
}
}
/** If an "recalc" Listener is added to this component it is wired to a [Recalc]
* button. We assume the action/button will recalc the summary mag.
* The ActionListener is defined by the caller and passed to this class. */
/* Alternatively we COULD recalc everytime there's a change. */
public void addRecalcListener (ActionListener listener) {
recalcListener = listener;
if (recalcButton == null) {
recalcButton = new JButton("Recalc");
recalcButton.setToolTipText("Recalculate the summary magnitude");
recalcButton.setAlignmentY(CENTER_ALIGNMENT);
recalcButton.setHorizontalTextPosition(AbstractButton.CENTER);
recalcButton.setVerticalTextPosition(AbstractButton.BOTTOM);
topPanel.add(recalcButton, BorderLayout.EAST);
}
recalcButton.addActionListener(recalcListener);
}
/** Remove listeners from other components so we are not a memory leak. */
public void destroy() {
if (readingList != null)
readingList.removeChangeListener(jasiReadingListListener);
}
/*
Make the GUI - generated with JBuilder
*/
private void jbInit() throws Exception {
this.setLayout(borderLayout1);
topPanel.setLayout(borderLayout2);
jlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jlist.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int mods = e.getModifiers();
// popup menu on right-click
if (e.isPopupTrigger() ||
(mods & MouseEvent.BUTTON3_MASK) != 0)
// only if something is selected
if (getSelectedReading() != null) makePopup(e.getPoint());
}
});
jlist.addKeyListener(new java.awt.event.KeyAdapter() {
// event is fired on both mouse down and release so don't act until release
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
// respond to [DEL] key
if (e.getKeyCode() == KeyEvent.VK_DELETE) {
deleteCurrentReading();
}
}
});
topPanel.add(summaryTextArea, BorderLayout.CENTER);
this.add(topPanel, BorderLayout.NORTH);
this.add(scroller, BorderLayout.CENTER);
scroller.getViewport().add(jlist, null);
}
/**
* Return the reading at this index in the list.
* Returns null if no readings in list, or index is out-of-bounds.
*/
public JasiReading getReading (int index) {
if (visibleList.isEmpty() || index < 0 || index > visibleList.size()) return null;
return (JasiReading) visibleList.get(index);
}
/** Return the currently selected reading. Returns null if no readings in list
or none selected.*/
public JasiReading getSelectedReading () {
return (JasiReading) jlist.getSelectedValue();
}
/** Delete the currently selected reading */
protected void deleteCurrentReading() {
JasiReading jreading = (JasiReading) jlist.getSelectedValue();
int oldIndex = jlist.getSelectedIndex();
readingList.delete(jreading); // This fires change event
// should keep "cursor" in same place but not fall off end
int newIndex = Math.min(oldIndex, jlist.getModel().getSize()-1);
if (newIndex > -1) jlist.setSelectedIndex(newIndex);
}
////////////////////////////////////////////////////////////////////////////////////
/** React to a changes in the jasi reading list. Changes (delete, add, etc.)
* may come from inside or outside this class. */
class JasiReadingListListener implements ChangeListener {
public void stateChanged (ChangeEvent evt) {
// just redo the list if ANYTHING changed in the readingList
setReadingList(readingList); // redo the whole thing
}
/*
int index = 0;
int oldIndex = jlist.getSelectedIndex();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -