Java tutorial
/******************************************************************************* * sdrtrunk * Copyright (C) 2014-2017 Dennis Sheirer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> * ******************************************************************************/ package io.github.dsheirer.channel.metadata; import io.github.dsheirer.alias.Alias; import io.github.dsheirer.channel.state.State; import io.github.dsheirer.controller.channel.Channel; import io.github.dsheirer.controller.channel.ChannelProcessingManager; import io.github.dsheirer.controller.channel.ChannelUtils; import io.github.dsheirer.icon.IconManager; import io.github.dsheirer.module.ProcessingChain; import io.github.dsheirer.properties.SystemProperties; import io.github.dsheirer.sample.Broadcaster; import io.github.dsheirer.sample.Listener; import net.miginfocom.swing.MigLayout; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableCellRenderer; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class ChannelMetadataPanel extends JPanel implements ListSelectionListener { private final static Logger mLog = LoggerFactory.getLogger(ChannelMetadataPanel.class); private static final String PROPERTY_PREFIX_BACKGROUND = "channel.metadata.panel.state.color."; private static final String PROPERTY_PREFIX_FOREGROUND = "channel.metadata.panel.text.color."; private ChannelProcessingManager mChannelProcessingManager; private IconManager mIconManager; private JTable mTable; private Broadcaster<ProcessingChain> mSelectedProcessingChainBroadcaster = new Broadcaster<>(); /** * Table view for currently decoding channel metadata */ public ChannelMetadataPanel(ChannelProcessingManager channelProcessingManager, IconManager iconManager) { mIconManager = iconManager; mChannelProcessingManager = channelProcessingManager; init(); } /** * Initializes the panel */ private void init() { setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]")); mTable = new JTable(mChannelProcessingManager.getChannelMetadataModel()); DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) mTable.getDefaultRenderer(String.class); renderer.setHorizontalAlignment(SwingConstants.CENTER); mTable.getSelectionModel().addListSelectionListener(this); mTable.addMouseListener(new MouseSupport()); mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_STATE) .setCellRenderer(new ColoredStateCellRenderer()); mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_PRIMARY_TO) .setCellRenderer(new AliasedValueCellRenderer(Attribute.PRIMARY_ADDRESS_TO)); mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_PRIMARY_FROM) .setCellRenderer(new AliasedValueCellRenderer(Attribute.PRIMARY_ADDRESS_FROM)); mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_SECONDARY_TO) .setCellRenderer(new AliasedValueCellRenderer(Attribute.SECONDARY_ADDRESS_TO)); mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_SECONDARY_FROM) .setCellRenderer(new AliasedValueCellRenderer(Attribute.SECONDARY_ADDRESS_FROM)); JScrollPane scrollPane = new JScrollPane(mTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); add(scrollPane); // new TableColumnWidthMonitor(mTable, PROPERTY_PREFIX, new int[] {15,15,15,15,25,25,25,25,15,40}); } @Override public void valueChanged(ListSelectionEvent e) { if (!mTable.getSelectionModel().getValueIsAdjusting()) { ProcessingChain processingChain = null; int selectedViewRow = mTable.getSelectedRow(); if (selectedViewRow >= 0) { int selectedModelRow = mTable.convertRowIndexToModel(selectedViewRow); Metadata selectedMetadata = mChannelProcessingManager.getChannelMetadataModel() .getMetadata(selectedModelRow); if (selectedMetadata != null) { Channel selectedChannel = mChannelProcessingManager.getChannelMetadataModel() .getChannelFromMetadata(selectedMetadata); processingChain = mChannelProcessingManager.getProcessingChain(selectedChannel); } } mSelectedProcessingChainBroadcaster.broadcast(processingChain); } } /** * Adds the listener to receive the processing chain associated with the metadata selected in the * metadata table. */ public void addProcessingChainSelectionListener(Listener<ProcessingChain> listener) { mSelectedProcessingChainBroadcaster.addListener(listener); } public class AliasedValueCellRenderer extends DefaultTableCellRenderer { private Attribute mAttribute; public AliasedValueCellRenderer(Attribute attribute) { Validate.isTrue(attribute != null); mAttribute = attribute; setHorizontalAlignment(JLabel.CENTER); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); Metadata metadata = (Metadata) value; String value1 = metadata.getValue(mAttribute); Alias alias = metadata.getAlias(mAttribute); label.setText(alias != null ? alias.getName() : value1); label.setIcon(alias != null ? mIconManager.getIcon(alias.getIconName(), IconManager.DEFAULT_ICON_SIZE) : null); label.setForeground(alias != null ? alias.getDisplayColor() : table.getForeground()); return label; } } public class ColoredStateCellRenderer extends DefaultTableCellRenderer { public ColoredStateCellRenderer() { setHorizontalAlignment(SwingConstants.CENTER); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); Color background = table.getBackground(); Color foreground = table.getForeground(); if (value instanceof State) { State state = (State) value; label.setText(state.getDisplayValue()); switch (state) { case CALL: background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "call", Color.BLUE); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "call", Color.YELLOW); break; case CONTROL: background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "control", Color.ORANGE); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "control", Color.BLUE); break; case DATA: background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "data", Color.GREEN); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "data", Color.BLUE); break; case ENCRYPTED: background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "encrypted", Color.MAGENTA); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "encrypted", Color.WHITE); break; case FADE: background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "fade", Color.LIGHT_GRAY.BLUE); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "fade", Color.YELLOW); break; case IDLE: background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "idle", Color.WHITE); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "idle", Color.BLUE); break; case OVERFLOW: background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "overflow", Color.RED); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "overflow", Color.YELLOW); break; case RESET: background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "reset", Color.PINK); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "reset", Color.YELLOW); break; case TEARDOWN: background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "teardown", Color.DARK_GRAY); foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "teardown", Color.WHITE); break; } } else { setText(""); } setBackground(background); setForeground(foreground); return label; } } public class MouseSupport extends MouseAdapter { @Override public void mouseClicked(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON3) //Right click for context { JPopupMenu popupMenu = new JPopupMenu(); boolean populated = false; int viewRowIndex = mTable.rowAtPoint(e.getPoint()); if (viewRowIndex >= 0) { int modelRowIndex = mTable.convertRowIndexToModel(viewRowIndex); if (modelRowIndex >= 0) { Metadata metadata = mChannelProcessingManager.getChannelMetadataModel() .getMetadata(modelRowIndex); if (metadata != null) { Channel channel = mChannelProcessingManager.getChannelMetadataModel() .getChannelFromMetadata(metadata); if (channel != null) { popupMenu.add( ChannelUtils.getContextMenu(mChannelProcessingManager.getChannelModel(), mChannelProcessingManager, channel, mTable)); populated = true; } } } } if (!populated) { popupMenu.add(new JMenuItem("No Actions Available")); } popupMenu.show(mTable, e.getX(), e.getY()); } } } }