mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 01:27:34 -05:00
Compare commits
10 Commits
v0.4.0-alp
...
v0.4.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
712eb07f4b | ||
|
|
d5c3ecc7df | ||
|
|
c4bf089667 | ||
|
|
378b03e06e | ||
|
|
34235382fb | ||
|
|
c05aff0768 | ||
|
|
f0c3e0fd1a | ||
|
|
d601cbda0e | ||
|
|
2653dc6b38 | ||
|
|
48cbbfc656 |
@@ -31,7 +31,7 @@ plugins {
|
|||||||
id 'java'
|
id 'java'
|
||||||
id 'idea'
|
id 'idea'
|
||||||
id 'org.openjfx.javafxplugin' version '0.0.6'
|
id 'org.openjfx.javafxplugin' version '0.0.6'
|
||||||
id 'org.beryx.runtime' version '1.1.1'
|
id 'org.beryx.runtime' version '1.1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@@ -39,7 +39,7 @@ repositories {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
version = '0.4.0-alpha.7'
|
version = '0.4.0-alpha.8'
|
||||||
sourceCompatibility = '11'
|
sourceCompatibility = '11'
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
|||||||
@@ -1,34 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
|
* sdrtrunk
|
||||||
|
* Copyright (C) 2014-2019 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.alias;
|
package io.github.dsheirer.alias;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideSplitPane;
|
import com.jidesoft.swing.JideSplitPane;
|
||||||
import io.github.dsheirer.audio.broadcast.BroadcastModel;
|
import io.github.dsheirer.audio.broadcast.BroadcastModel;
|
||||||
import io.github.dsheirer.gui.editor.Editor;
|
import io.github.dsheirer.gui.editor.Editor;
|
||||||
import io.github.dsheirer.icon.IconManager;
|
import io.github.dsheirer.icon.IconManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import net.coderazzi.filters.gui.AutoChoices;
|
import net.coderazzi.filters.gui.AutoChoices;
|
||||||
import net.coderazzi.filters.gui.TableFilterHeader;
|
import net.coderazzi.filters.gui.TableFilterHeader;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import java.awt.*;
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AliasController extends JPanel
|
public class AliasController extends JPanel implements ActionListener, ListSelectionListener
|
||||||
implements ActionListener, ListSelectionListener
|
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "alias.controller";
|
||||||
private AliasModel mAliasModel;
|
private AliasModel mAliasModel;
|
||||||
private JTable mAliasTable;
|
private JTable mAliasTable;
|
||||||
private TableFilterHeader mTableFilterHeader;
|
private TableFilterHeader mTableFilterHeader;
|
||||||
private AliasEditor mAliasEditor;
|
private AliasEditor mAliasEditor;
|
||||||
private MultipleAliasEditor mMultipleAliasEditor;
|
private MultipleAliasEditor mMultipleAliasEditor;
|
||||||
private JideSplitPane mSplitPane;
|
private JideSplitPane mSplitPane;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
|
||||||
private static final String NEW_ALIAS = "New";
|
private static final String NEW_ALIAS = "New";
|
||||||
private static final String COPY_ALIAS = "Copy";
|
private static final String COPY_ALIAS = "Copy";
|
||||||
@@ -39,15 +72,16 @@ public class AliasController extends JPanel
|
|||||||
private JButton mDeleteButton = new JButton(DELETE_ALIAS);
|
private JButton mDeleteButton = new JButton(DELETE_ALIAS);
|
||||||
|
|
||||||
private IconCellRenderer mIconCellRenderer;
|
private IconCellRenderer mIconCellRenderer;
|
||||||
|
private JTableColumnWidthMonitor mColumnWidthMonitor;
|
||||||
|
|
||||||
public AliasController(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager)
|
public AliasController(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mAliasModel = aliasModel;
|
mAliasModel = aliasModel;
|
||||||
|
|
||||||
mAliasEditor = new AliasEditor(mAliasModel, broadcastModel, iconManager);
|
mAliasEditor = new AliasEditor(mAliasModel, broadcastModel, iconManager);
|
||||||
mMultipleAliasEditor = new MultipleAliasEditor(mAliasModel, broadcastModel, iconManager);
|
mMultipleAliasEditor = new MultipleAliasEditor(mAliasModel, broadcastModel, iconManager);
|
||||||
|
|
||||||
mIconCellRenderer = new IconCellRenderer(iconManager);
|
mIconCellRenderer = new IconCellRenderer(iconManager);
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
@@ -56,9 +90,7 @@ public class AliasController extends JPanel
|
|||||||
|
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0",
|
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]"));
|
||||||
"[grow,fill]",
|
|
||||||
"[grow,fill]"));
|
|
||||||
|
|
||||||
//System Configuration View and Editor
|
//System Configuration View and Editor
|
||||||
mAliasTable = new JTable(mAliasModel);
|
mAliasTable = new JTable(mAliasModel);
|
||||||
@@ -66,11 +98,11 @@ public class AliasController extends JPanel
|
|||||||
mAliasTable.getSelectionModel().addListSelectionListener(this);
|
mAliasTable.getSelectionModel().addListSelectionListener(this);
|
||||||
mAliasTable.setAutoCreateRowSorter(true);
|
mAliasTable.setAutoCreateRowSorter(true);
|
||||||
|
|
||||||
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_COLOR)
|
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_COLOR).setCellRenderer(new ColorCellRenderer());
|
||||||
.setCellRenderer(new ColorCellRenderer());
|
|
||||||
|
|
||||||
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_ICON)
|
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_ICON).setCellRenderer(mIconCellRenderer);
|
||||||
.setCellRenderer(mIconCellRenderer);
|
|
||||||
|
mColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mAliasTable, TABLE_PREFERENCE_KEY);
|
||||||
|
|
||||||
mTableFilterHeader = new TableFilterHeader(mAliasTable, AutoChoices.ENABLED);
|
mTableFilterHeader = new TableFilterHeader(mAliasTable, AutoChoices.ENABLED);
|
||||||
mTableFilterHeader.setFilterOnUpdates(true);
|
mTableFilterHeader.setFilterOnUpdates(true);
|
||||||
@@ -79,8 +111,8 @@ public class AliasController extends JPanel
|
|||||||
|
|
||||||
JPanel buttonsPanel = new JPanel();
|
JPanel buttonsPanel = new JPanel();
|
||||||
|
|
||||||
buttonsPanel.setLayout(
|
buttonsPanel.setLayout(new MigLayout("insets 0 0 0 0",
|
||||||
new MigLayout("insets 0 0 0 0", "[grow,fill][grow,fill][grow,fill]", "[]"));
|
"[grow,fill][grow,fill][grow,fill]", "[]"));
|
||||||
|
|
||||||
mNewButton.addActionListener(this);
|
mNewButton.addActionListener(this);
|
||||||
mNewButton.setToolTipText("Adds a new alias");
|
mNewButton.setToolTipText("Adds a new alias");
|
||||||
@@ -98,8 +130,8 @@ public class AliasController extends JPanel
|
|||||||
|
|
||||||
JPanel listAndButtonsPanel = new JPanel();
|
JPanel listAndButtonsPanel = new JPanel();
|
||||||
|
|
||||||
listAndButtonsPanel.setLayout(
|
listAndButtonsPanel.setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]",
|
||||||
new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill][]"));
|
"[grow,fill][]"));
|
||||||
|
|
||||||
listAndButtonsPanel.add(tableScroller, "wrap");
|
listAndButtonsPanel.add(tableScroller, "wrap");
|
||||||
listAndButtonsPanel.add(buttonsPanel);
|
listAndButtonsPanel.add(buttonsPanel);
|
||||||
@@ -212,18 +244,11 @@ public class AliasController extends JPanel
|
|||||||
*/
|
*/
|
||||||
private void addAlias(Alias alias)
|
private void addAlias(Alias alias)
|
||||||
{
|
{
|
||||||
//HACK: when inserting a row to the model, the JTable gets
|
//Remove any column headers so that the newly added alias shows correctly.
|
||||||
//notified and attempts to tell the coderazzi table filter
|
mTableFilterHeader.resetFilter();
|
||||||
//adaptive choices filter to refresh before the table filter is
|
|
||||||
//notified of the row additions, causing an index out of bounds
|
|
||||||
//exception. We turn off adaptive choices temporarily, add the
|
|
||||||
//channel, and turn on adaptive choices again.
|
|
||||||
mTableFilterHeader.setAdaptiveChoices(false);
|
|
||||||
|
|
||||||
int index = mAliasModel.addAlias(alias);
|
int index = mAliasModel.addAlias(alias);
|
||||||
|
|
||||||
mTableFilterHeader.setAdaptiveChoices(true);
|
|
||||||
|
|
||||||
if(index >= 0)
|
if(index >= 0)
|
||||||
{
|
{
|
||||||
int translatedIndex = mAliasTable.convertRowIndexToView(index);
|
int translatedIndex = mAliasTable.convertRowIndexToView(index);
|
||||||
|
|||||||
@@ -505,11 +505,32 @@ public class AliasList implements Listener<AliasEvent>
|
|||||||
|
|
||||||
public void add(Talkgroup talkgroup, Alias alias)
|
public void add(Talkgroup talkgroup, Alias alias)
|
||||||
{
|
{
|
||||||
|
//Detect talkgroup collisions
|
||||||
|
if(mTalkgroupAliasMap.containsKey(talkgroup.getValue()))
|
||||||
|
{
|
||||||
|
Alias existing = mTalkgroupAliasMap.get(talkgroup.getValue());
|
||||||
|
|
||||||
|
mLog.warn("Alias [" + alias.getName() + "] talkgroup [" + talkgroup.getValue() +
|
||||||
|
"] has the same talkgroup value as alias [" + existing.getName() +
|
||||||
|
"] - alias [" + alias.getName() + "] will be used for alias list [" + getName() + "]");
|
||||||
|
}
|
||||||
|
|
||||||
mTalkgroupAliasMap.put(talkgroup.getValue(), alias);
|
mTalkgroupAliasMap.put(talkgroup.getValue(), alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(TalkgroupRange talkgroupRange, Alias alias)
|
public void add(TalkgroupRange talkgroupRange, Alias alias)
|
||||||
{
|
{
|
||||||
|
//Log warning if the new talkgroup range overlaps with any existing ranges
|
||||||
|
for(Map.Entry<TalkgroupRange,Alias> entry: mTalkgroupRangeAliasMap.entrySet())
|
||||||
|
{
|
||||||
|
if(talkgroupRange.overlaps(entry.getKey()))
|
||||||
|
{
|
||||||
|
mLog.warn("Alias [" + alias.getName() + "] with talkgroup range [" + talkgroupRange.toString() +
|
||||||
|
"] overlaps with alias [" + entry.getValue().getName() +
|
||||||
|
"] with talkgroup range [" + entry.getKey().toString() + "] for alias list [" + getName() + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mTalkgroupRangeAliasMap.put(talkgroupRange, alias);
|
mTalkgroupRangeAliasMap.put(talkgroupRange, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,6 +140,21 @@ public class TalkgroupRange extends AliasID
|
|||||||
return getMinTalkgroup() <= talkgroupValue && talkgroupValue <= getMaxTalkgroup();
|
return getMinTalkgroup() <= talkgroupValue && talkgroupValue <= getMaxTalkgroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this talkgroup range overlaps the talkgroup range argument.
|
||||||
|
* @param talkgroupRange to check for overlap
|
||||||
|
* @return true if the ranges overlap
|
||||||
|
*/
|
||||||
|
public boolean overlaps(TalkgroupRange talkgroupRange)
|
||||||
|
{
|
||||||
|
return contains(talkgroupRange.getMinTalkgroup()) ||
|
||||||
|
contains(talkgroupRange.getMaxTalkgroup()) ||
|
||||||
|
(getMinTalkgroup() < talkgroupRange.getMinTalkgroup() &&
|
||||||
|
talkgroupRange.getMaxTalkgroup() < getMaxTalkgroup()) ||
|
||||||
|
(talkgroupRange.getMinTalkgroup() < getMinTalkgroup() &&
|
||||||
|
getMaxTalkgroup() < talkgroupRange.getMaxTalkgroup());
|
||||||
|
}
|
||||||
|
|
||||||
@JacksonXmlProperty(isAttribute = true, localName = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
|
@JacksonXmlProperty(isAttribute = true, localName = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
|
||||||
@Override
|
@Override
|
||||||
public AliasIDType getType()
|
public AliasIDType getType()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +15,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.audio.broadcast;
|
package io.github.dsheirer.audio.broadcast;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideSplitPane;
|
import com.jidesoft.swing.JideSplitPane;
|
||||||
@@ -23,6 +24,7 @@ import io.github.dsheirer.alias.AliasModel;
|
|||||||
import io.github.dsheirer.gui.editor.Editor;
|
import io.github.dsheirer.gui.editor.Editor;
|
||||||
import io.github.dsheirer.gui.editor.EmptyEditor;
|
import io.github.dsheirer.gui.editor.EmptyEditor;
|
||||||
import io.github.dsheirer.icon.IconManager;
|
import io.github.dsheirer.icon.IconManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -51,6 +53,7 @@ public class BroadcastPanel extends JPanel implements ActionListener, ListSelect
|
|||||||
private BroadcastModel mBroadcastModel;
|
private BroadcastModel mBroadcastModel;
|
||||||
private AliasModel mAliasModel;
|
private AliasModel mAliasModel;
|
||||||
private IconManager mIconManager;
|
private IconManager mIconManager;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
|
||||||
private BroadcastStatusPanel mBroadcastStatusPanel;
|
private BroadcastStatusPanel mBroadcastStatusPanel;
|
||||||
private JideSplitPane mSplitPane;
|
private JideSplitPane mSplitPane;
|
||||||
@@ -60,12 +63,14 @@ public class BroadcastPanel extends JPanel implements ActionListener, ListSelect
|
|||||||
private JButton mCopyButton = new JButton(COPY_BROADCAST_CONFIGURATION);
|
private JButton mCopyButton = new JButton(COPY_BROADCAST_CONFIGURATION);
|
||||||
private JButton mDeleteButton = new JButton(DELETE_BROADCAST_CONFIGURATION);
|
private JButton mDeleteButton = new JButton(DELETE_BROADCAST_CONFIGURATION);
|
||||||
|
|
||||||
public BroadcastPanel(BroadcastModel broadcastModel, AliasModel aliasModel, IconManager iconManager)
|
public BroadcastPanel(BroadcastModel broadcastModel, AliasModel aliasModel, IconManager iconManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mBroadcastModel = broadcastModel;
|
mBroadcastModel = broadcastModel;
|
||||||
mAliasModel = aliasModel;
|
mAliasModel = aliasModel;
|
||||||
mIconManager = iconManager;
|
mIconManager = iconManager;
|
||||||
mEditor = mEmptyEditor;
|
mEditor = mEmptyEditor;
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -74,7 +79,8 @@ public class BroadcastPanel extends JPanel implements ActionListener, ListSelect
|
|||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]"));
|
setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]"));
|
||||||
|
|
||||||
mBroadcastStatusPanel = new BroadcastStatusPanel(mBroadcastModel);
|
mBroadcastStatusPanel = new BroadcastStatusPanel(mBroadcastModel, mUserPreferences,
|
||||||
|
"broadcast.panel.broadcast.status.panel");
|
||||||
|
|
||||||
mBroadcastStatusPanel.getTable().setAutoCreateRowSorter(true);
|
mBroadcastStatusPanel.getTable().setAutoCreateRowSorter(true);
|
||||||
mBroadcastStatusPanel.getTable().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
mBroadcastStatusPanel.getTable().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,10 +15,12 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.audio.broadcast;
|
package io.github.dsheirer.audio.broadcast;
|
||||||
|
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
@@ -32,12 +35,17 @@ import java.awt.Component;
|
|||||||
public class BroadcastStatusPanel extends JPanel
|
public class BroadcastStatusPanel extends JPanel
|
||||||
{
|
{
|
||||||
private JTable mTable;
|
private JTable mTable;
|
||||||
|
private JTableColumnWidthMonitor mColumnWidthMonitor;
|
||||||
private JScrollPane mScrollPane;
|
private JScrollPane mScrollPane;
|
||||||
private BroadcastModel mBroadcastModel;
|
private BroadcastModel mBroadcastModel;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
private String mPreferenceKey;
|
||||||
|
|
||||||
public BroadcastStatusPanel(BroadcastModel broadcastModel)
|
public BroadcastStatusPanel(BroadcastModel broadcastModel, UserPreferences userPreferences, String preferenceKey)
|
||||||
{
|
{
|
||||||
mBroadcastModel = broadcastModel;
|
mBroadcastModel = broadcastModel;
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
mPreferenceKey = preferenceKey;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -57,6 +65,7 @@ public class BroadcastStatusPanel extends JPanel
|
|||||||
renderer.setHorizontalAlignment(SwingConstants.CENTER);
|
renderer.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
|
||||||
mTable.getColumnModel().getColumn(BroadcastModel.COLUMN_BROADCASTER_STATUS).setCellRenderer(new StatusCellRenderer());
|
mTable.getColumnModel().getColumn(BroadcastModel.COLUMN_BROADCASTER_STATUS).setCellRenderer(new StatusCellRenderer());
|
||||||
|
mColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, mPreferenceKey);
|
||||||
|
|
||||||
mScrollPane = new JScrollPane(mTable);
|
mScrollPane = new JScrollPane(mTable);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +15,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.audio.broadcast.icecast;
|
package io.github.dsheirer.audio.broadcast.icecast;
|
||||||
|
|
||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
@@ -30,11 +31,9 @@ import org.apache.mina.core.service.IoHandlerAdapter;
|
|||||||
import org.apache.mina.core.session.IoSession;
|
import org.apache.mina.core.session.IoSession;
|
||||||
import org.apache.mina.filter.codec.ProtocolDecoderException;
|
import org.apache.mina.filter.codec.ProtocolDecoderException;
|
||||||
import org.apache.mina.http.HttpClientCodec;
|
import org.apache.mina.http.HttpClientCodec;
|
||||||
import org.apache.mina.http.HttpException;
|
|
||||||
import org.apache.mina.http.HttpRequestImpl;
|
import org.apache.mina.http.HttpRequestImpl;
|
||||||
import org.apache.mina.http.api.DefaultHttpResponse;
|
import org.apache.mina.http.api.DefaultHttpResponse;
|
||||||
import org.apache.mina.http.api.HttpMethod;
|
import org.apache.mina.http.api.HttpMethod;
|
||||||
import org.apache.mina.http.api.HttpStatus;
|
|
||||||
import org.apache.mina.http.api.HttpVersion;
|
import org.apache.mina.http.api.HttpVersion;
|
||||||
import org.apache.mina.transport.socket.nio.NioSocketConnector;
|
import org.apache.mina.transport.socket.nio.NioSocketConnector;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -51,6 +50,7 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
{
|
{
|
||||||
private static final Logger mLog = LoggerFactory.getLogger(IcecastHTTPAudioBroadcaster.class);
|
private static final Logger mLog = LoggerFactory.getLogger(IcecastHTTPAudioBroadcaster.class);
|
||||||
private static final long RECONNECT_INTERVAL_MILLISECONDS = 30000; //30 seconds
|
private static final long RECONNECT_INTERVAL_MILLISECONDS = 30000; //30 seconds
|
||||||
|
private static final String HTTP_1_0_OK_HEX_DUMP = "48 54 54 50 2F 31 2E 30 20 32 30 30 20 4F 4B";
|
||||||
|
|
||||||
private NioSocketConnector mSocketConnector;
|
private NioSocketConnector mSocketConnector;
|
||||||
private IoSession mStreamingSession = null;
|
private IoSession mStreamingSession = null;
|
||||||
@@ -113,7 +113,7 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
mSocketConnector.setConnectTimeoutCheckInterval(10000);
|
mSocketConnector.setConnectTimeoutCheckInterval(10000);
|
||||||
|
|
||||||
// mSocketConnector.getFilterChain().addLast("logger",
|
// mSocketConnector.getFilterChain().addLast("logger",
|
||||||
// new LoggingFilter(IcecastTCPAudioBroadcaster.class));
|
// new LoggingFilter(IcecastHTTPAudioBroadcaster.class));
|
||||||
|
|
||||||
mSocketConnector.getFilterChain().addLast("codec", new HttpClientCodec());
|
mSocketConnector.getFilterChain().addLast("codec", new HttpClientCodec());
|
||||||
mSocketConnector.setHandler(new IcecastHTTPIOHandler());
|
mSocketConnector.setHandler(new IcecastHTTPIOHandler());
|
||||||
@@ -266,13 +266,18 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
{
|
{
|
||||||
if(throwable instanceof ProtocolDecoderException)
|
if(throwable instanceof ProtocolDecoderException)
|
||||||
{
|
{
|
||||||
Throwable cause = ((ProtocolDecoderException) throwable).getCause();
|
Throwable cause = throwable.getCause();
|
||||||
|
|
||||||
if(cause instanceof HttpException &&
|
/**
|
||||||
((HttpException) cause).getStatusCode() == HttpStatus.CLIENT_ERROR_LENGTH_REQUIRED.code())
|
* Warning: Hack. Icecast 2.4.2+ doesn't like to send HTTP headers along with their HTTP/1.0 OK
|
||||||
|
* message which causes Apache Mina to think that it hasn't received the full HTTP response. So, we
|
||||||
|
* intercept the out of bounds exception and then inspect the message hex dump to see if it's an
|
||||||
|
* OK response and then play like everything is well and good.
|
||||||
|
*/
|
||||||
|
if(cause instanceof ArrayIndexOutOfBoundsException &&
|
||||||
|
((ProtocolDecoderException)throwable).getHexdump().startsWith(HTTP_1_0_OK_HEX_DUMP))
|
||||||
{
|
{
|
||||||
//Ignore - Icecast 2.4 sometimes doesn't send any headers with their HTTP responses. Mina expects a
|
setBroadcastState(BroadcastState.CONNECTED);
|
||||||
//content-length for HTTP responses.
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -83,8 +83,6 @@ public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, S
|
|||||||
private JLabel mIdentifierLabel = new JLabel("-----");
|
private JLabel mIdentifierLabel = new JLabel("-----");
|
||||||
private Identifier mIdentifier;
|
private Identifier mIdentifier;
|
||||||
private List<Alias> mAliases = Collections.EMPTY_LIST;
|
private List<Alias> mAliases = Collections.EMPTY_LIST;
|
||||||
|
|
||||||
private boolean mConfigured = false;
|
|
||||||
private AliasModel mAliasModel;
|
private AliasModel mAliasModel;
|
||||||
|
|
||||||
public AudioChannelPanel(IconManager iconManager, UserPreferences userPreferences, SettingsManager settingsManager,
|
public AudioChannelPanel(IconManager iconManager, UserPreferences userPreferences, SettingsManager settingsManager,
|
||||||
@@ -191,31 +189,71 @@ public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, S
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the from and to labels. Note: this does not happen on the swing
|
* Resets the from and to labels.
|
||||||
* event thread. Only invoke from the swing thread.
|
|
||||||
*/
|
*/
|
||||||
private void resetLabels()
|
private void resetLabels()
|
||||||
{
|
{
|
||||||
|
boolean updated = mIdentifier != null;
|
||||||
mIdentifier = null;
|
mIdentifier = null;
|
||||||
mAliases = Collections.EMPTY_LIST;
|
mAliases = Collections.EMPTY_LIST;
|
||||||
updateLabels();
|
|
||||||
mConfigured = false;
|
if(updated)
|
||||||
|
{
|
||||||
|
updateLabels();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void updateIdentifiers(IdentifierCollection identifierCollection)
|
||||||
* Truncates the string to the specified length using an ellipses at the end
|
|
||||||
* @param value to optionally truncate
|
|
||||||
* @param length of the final formatted string
|
|
||||||
* @return formatted string or null
|
|
||||||
*/
|
|
||||||
private static String truncate(String value, int length)
|
|
||||||
{
|
{
|
||||||
if(value != null && value.length() > length)
|
if(identifierCollection == null || identifierCollection.isEmpty())
|
||||||
{
|
{
|
||||||
return value.substring(0, length - 3) + "...";
|
resetLabels();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
List<Identifier> toIds = identifierCollection.getIdentifiers(IdentifierClass.USER, Role.TO);
|
||||||
|
|
||||||
|
if(toIds.isEmpty())
|
||||||
|
{
|
||||||
|
resetLabels();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean updated = false;
|
||||||
|
|
||||||
|
if(toIds.size() == 1)
|
||||||
|
{
|
||||||
|
Identifier currentIdentifier = mIdentifier;
|
||||||
|
|
||||||
|
if(currentIdentifier == null || currentIdentifier != toIds.get(0))
|
||||||
|
{
|
||||||
|
mIdentifier = toIds.get(0);
|
||||||
|
AliasList aliasList = mAliasModel.getAliasList(identifierCollection);
|
||||||
|
|
||||||
|
if(aliasList != null)
|
||||||
|
{
|
||||||
|
mAliases = aliasList.getAliases(mIdentifier);
|
||||||
|
}
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.warn("Multiple To Identifiers in Collection: " + Joiner.on(",").join(toIds));
|
||||||
|
mIdentifier = toIds.get(0);
|
||||||
|
AliasList aliasList = mAliasModel.getAliasList(identifierCollection);
|
||||||
|
|
||||||
|
if(aliasList != null)
|
||||||
|
{
|
||||||
|
mAliases = aliasList.getAliases(mIdentifier);
|
||||||
|
}
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updated)
|
||||||
|
{
|
||||||
|
updateLabels();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -249,7 +287,8 @@ public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, S
|
|||||||
}
|
}
|
||||||
|
|
||||||
final ImageIcon icon = iconName != null ? mIconManager.getIcon(iconName, 18) : null;
|
final ImageIcon icon = iconName != null ? mIconManager.getIcon(iconName, 18) : null;
|
||||||
final String identifierText = truncate(identifier, 33);
|
|
||||||
|
final String identifierText = identifier;
|
||||||
|
|
||||||
EventQueue.invokeLater(new Runnable()
|
EventQueue.invokeLater(new Runnable()
|
||||||
{
|
{
|
||||||
@@ -258,7 +297,6 @@ public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, S
|
|||||||
{
|
{
|
||||||
mIdentifierLabel.setText(identifierText);
|
mIdentifierLabel.setText(identifierText);
|
||||||
mIconLabel.setIcon(icon);
|
mIconLabel.setIcon(icon);
|
||||||
mConfigured = true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -272,23 +310,10 @@ public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, S
|
|||||||
@Override
|
@Override
|
||||||
public void receive(final IdentifierCollection identifierCollection)
|
public void receive(final IdentifierCollection identifierCollection)
|
||||||
{
|
{
|
||||||
if(identifierCollection != null && (identifierCollection.isUpdated() || !mConfigured))
|
updateIdentifiers(identifierCollection);
|
||||||
{
|
|
||||||
List<Identifier> toIds = identifierCollection.getIdentifiers(IdentifierClass.USER, Role.TO);
|
|
||||||
mIdentifier = !toIds.isEmpty() ? toIds.get(0) : null;
|
|
||||||
AliasList aliasList = mAliasModel.getAliasList(identifierCollection);
|
|
||||||
|
|
||||||
if(aliasList != null)
|
|
||||||
{
|
|
||||||
mAliases = aliasList.getAliases(mIdentifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateLabels();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void settingChanged(Setting setting)
|
public void settingChanged(Setting setting)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -39,7 +39,8 @@ public class AudioChannelsPanel extends JPanel
|
|||||||
public AudioChannelsPanel(IconManager iconManager, UserPreferences userPreferences, SettingsManager settingsManager,
|
public AudioChannelsPanel(IconManager iconManager, UserPreferences userPreferences, SettingsManager settingsManager,
|
||||||
IAudioController controller, AliasModel aliasModel)
|
IAudioController controller, AliasModel aliasModel)
|
||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[][sg abc,grow,fill][][sg abc,grow,fill]", "[grow,fill]"));
|
setLayout(new MigLayout("insets 0 0 0 0",
|
||||||
|
"[][sizegroup abc,grow,fill][][sizegroup abc,grow,fill]", "[grow,fill]"));
|
||||||
|
|
||||||
setBackground(Color.BLACK);
|
setBackground(Color.BLACK);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -54,6 +54,11 @@ public abstract class AudioOutput implements Listener<ReusableAudioPacket>, Line
|
|||||||
private LinkedTransferQueue<ReusableAudioPacket> mBuffer = new LinkedTransferQueue<>();
|
private LinkedTransferQueue<ReusableAudioPacket> mBuffer = new LinkedTransferQueue<>();
|
||||||
private int mBufferStartThreshold;
|
private int mBufferStartThreshold;
|
||||||
private int mBufferStopThreshold;
|
private int mBufferStopThreshold;
|
||||||
|
private static IdentifierCollection EMPTY_IDENTIFIER_COLLECTION = new IdentifierCollection();
|
||||||
|
static
|
||||||
|
{
|
||||||
|
EMPTY_IDENTIFIER_COLLECTION.setUpdated(true);
|
||||||
|
}
|
||||||
|
|
||||||
private Listener<IdentifierCollection> mIdentifierCollectionListener;
|
private Listener<IdentifierCollection> mIdentifierCollectionListener;
|
||||||
private Broadcaster<AudioEvent> mAudioEventBroadcaster = new Broadcaster<>();
|
private Broadcaster<AudioEvent> mAudioEventBroadcaster = new Broadcaster<>();
|
||||||
@@ -380,12 +385,11 @@ public abstract class AudioOutput implements Listener<ReusableAudioPacket>, Line
|
|||||||
*/
|
*/
|
||||||
private void checkStop()
|
private void checkStop()
|
||||||
{
|
{
|
||||||
if(mCanProcessAudio &&
|
if(mCanProcessAudio && mOutput.isRunning() && mOutput.available() >= mBufferStopThreshold)
|
||||||
mOutput.isRunning() &&
|
|
||||||
mOutput.available() >= mBufferStopThreshold)
|
|
||||||
{
|
{
|
||||||
mOutput.drain();
|
mOutput.drain();
|
||||||
mOutput.stop();
|
mOutput.stop();
|
||||||
|
broadcast(EMPTY_IDENTIFIER_COLLECTION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import io.github.dsheirer.identifier.decoder.ChannelStateIdentifier;
|
|||||||
import io.github.dsheirer.module.ProcessingChain;
|
import io.github.dsheirer.module.ProcessingChain;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.preference.identifier.TalkgroupFormatPreference;
|
import io.github.dsheirer.preference.identifier.TalkgroupFormatPreference;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import io.github.dsheirer.sample.Broadcaster;
|
import io.github.dsheirer.sample.Broadcaster;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
@@ -58,6 +59,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class ChannelMetadataPanel extends JPanel implements ListSelectionListener
|
public class ChannelMetadataPanel extends JPanel implements ListSelectionListener
|
||||||
{
|
{
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "channel.metadata.panel";
|
||||||
private ChannelModel mChannelModel;
|
private ChannelModel mChannelModel;
|
||||||
private ChannelProcessingManager mChannelProcessingManager;
|
private ChannelProcessingManager mChannelProcessingManager;
|
||||||
private IconManager mIconManager;
|
private IconManager mIconManager;
|
||||||
@@ -66,6 +68,7 @@ public class ChannelMetadataPanel extends JPanel implements ListSelectionListene
|
|||||||
private Broadcaster<ProcessingChain> mSelectedProcessingChainBroadcaster = new Broadcaster<>();
|
private Broadcaster<ProcessingChain> mSelectedProcessingChainBroadcaster = new Broadcaster<>();
|
||||||
private Map<State,Color> mBackgroundColors = new HashMap<>();
|
private Map<State,Color> mBackgroundColors = new HashMap<>();
|
||||||
private Map<State,Color> mForegroundColors = new HashMap<>();
|
private Map<State,Color> mForegroundColors = new HashMap<>();
|
||||||
|
private JTableColumnWidthMonitor mTableColumnMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table view for currently decoding channel metadata
|
* Table view for currently decoding channel metadata
|
||||||
@@ -108,6 +111,9 @@ public class ChannelMetadataPanel extends JPanel implements ListSelectionListene
|
|||||||
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_CONFIGURATION_FREQUENCY)
|
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_CONFIGURATION_FREQUENCY)
|
||||||
.setCellRenderer(new FrequencyCellRenderer());
|
.setCellRenderer(new FrequencyCellRenderer());
|
||||||
|
|
||||||
|
//Add a table column width monitor to store/restore column widths
|
||||||
|
mTableColumnMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, TABLE_PREFERENCE_KEY);
|
||||||
|
|
||||||
JScrollPane scrollPane = new JScrollPane(mTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
JScrollPane scrollPane = new JScrollPane(mTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
||||||
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +15,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.channel.metadata;
|
package io.github.dsheirer.channel.metadata;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideSplitPane;
|
import com.jidesoft.swing.JideSplitPane;
|
||||||
@@ -33,10 +34,9 @@ import net.miginfocom.swing.MigLayout;
|
|||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
public class ChannelMetadataViewer extends JPanel
|
public class NowPlayingPanel extends JPanel
|
||||||
{
|
{
|
||||||
private ChannelMetadataPanel mChannelMetadataPanel;
|
private ChannelMetadataPanel mChannelMetadataPanel;
|
||||||
|
|
||||||
private ChannelDetailPanel mChannelDetailPanel;
|
private ChannelDetailPanel mChannelDetailPanel;
|
||||||
private DecodeEventPanel mDecodeEventPanel;
|
private DecodeEventPanel mDecodeEventPanel;
|
||||||
private MessageActivityPanel mMessageActivityPanel;
|
private MessageActivityPanel mMessageActivityPanel;
|
||||||
@@ -45,12 +45,12 @@ public class ChannelMetadataViewer extends JPanel
|
|||||||
* GUI panel that combines the currently decoding channels metadata table and viewers for channel details,
|
* GUI panel that combines the currently decoding channels metadata table and viewers for channel details,
|
||||||
* messages, events, and spectral view.
|
* messages, events, and spectral view.
|
||||||
*/
|
*/
|
||||||
public ChannelMetadataViewer(ChannelModel channelModel, ChannelProcessingManager channelProcessingManager,
|
public NowPlayingPanel(ChannelModel channelModel, ChannelProcessingManager channelProcessingManager,
|
||||||
IconManager iconManager, AliasModel aliasModel, UserPreferences userPreferences)
|
IconManager iconManager, AliasModel aliasModel, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mChannelDetailPanel = new ChannelDetailPanel(channelProcessingManager);
|
mChannelDetailPanel = new ChannelDetailPanel(channelProcessingManager);
|
||||||
mDecodeEventPanel = new DecodeEventPanel(iconManager, userPreferences, aliasModel);
|
mDecodeEventPanel = new DecodeEventPanel(iconManager, userPreferences, aliasModel);
|
||||||
mMessageActivityPanel = new MessageActivityPanel(channelProcessingManager);
|
mMessageActivityPanel = new MessageActivityPanel(userPreferences);
|
||||||
mChannelMetadataPanel = new ChannelMetadataPanel(channelModel, channelProcessingManager, iconManager, userPreferences);
|
mChannelMetadataPanel = new ChannelMetadataPanel(channelModel, channelProcessingManager, iconManager, userPreferences);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
@@ -64,7 +64,6 @@ public class ChannelMetadataViewer extends JPanel
|
|||||||
tabbedPane.addTab("Details", mChannelDetailPanel);
|
tabbedPane.addTab("Details", mChannelDetailPanel);
|
||||||
tabbedPane.addTab("Events", mDecodeEventPanel);
|
tabbedPane.addTab("Events", mDecodeEventPanel);
|
||||||
tabbedPane.addTab("Messages", mMessageActivityPanel);
|
tabbedPane.addTab("Messages", mMessageActivityPanel);
|
||||||
// tabbedPane.addTab("Spectrum", mChannelSpectrumPanel);
|
|
||||||
tabbedPane.setFont(this.getFont());
|
tabbedPane.setFont(this.getFont());
|
||||||
tabbedPane.setForeground(Color.BLACK);
|
tabbedPane.setForeground(Color.BLACK);
|
||||||
|
|
||||||
@@ -28,6 +28,7 @@ import io.github.dsheirer.controller.channel.Channel;
|
|||||||
import io.github.dsheirer.controller.channel.Channel.ChannelType;
|
import io.github.dsheirer.controller.channel.Channel.ChannelType;
|
||||||
import io.github.dsheirer.controller.channel.ChannelEvent;
|
import io.github.dsheirer.controller.channel.ChannelEvent;
|
||||||
import io.github.dsheirer.controller.channel.IChannelEventProvider;
|
import io.github.dsheirer.controller.channel.IChannelEventProvider;
|
||||||
|
import io.github.dsheirer.identifier.IdentifierClass;
|
||||||
import io.github.dsheirer.identifier.IdentifierUpdateListener;
|
import io.github.dsheirer.identifier.IdentifierUpdateListener;
|
||||||
import io.github.dsheirer.identifier.IdentifierUpdateNotification;
|
import io.github.dsheirer.identifier.IdentifierUpdateNotification;
|
||||||
import io.github.dsheirer.identifier.IdentifierUpdateProvider;
|
import io.github.dsheirer.identifier.IdentifierUpdateProvider;
|
||||||
@@ -203,6 +204,7 @@ public class ChannelState extends Module implements IChannelEventProvider, IDeco
|
|||||||
{
|
{
|
||||||
mState = State.IDLE;
|
mState = State.IDLE;
|
||||||
broadcast(new DecoderStateEvent(this, Event.RESET, State.IDLE));
|
broadcast(new DecoderStateEvent(this, Event.RESET, State.IDLE));
|
||||||
|
mIdentifierCollection.remove(IdentifierClass.USER);
|
||||||
mIdentifierCollection.update(ChannelStateIdentifier.IDLE);
|
mIdentifierCollection.update(ChannelStateIdentifier.IDLE);
|
||||||
mSourceOverflow = false;
|
mSourceOverflow = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +15,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.controller;
|
package io.github.dsheirer.controller;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideTabbedPane;
|
import com.jidesoft.swing.JideTabbedPane;
|
||||||
@@ -25,7 +26,7 @@ import io.github.dsheirer.audio.broadcast.BroadcastModel;
|
|||||||
import io.github.dsheirer.audio.broadcast.BroadcastPanel;
|
import io.github.dsheirer.audio.broadcast.BroadcastPanel;
|
||||||
import io.github.dsheirer.audio.playback.AudioPanel;
|
import io.github.dsheirer.audio.playback.AudioPanel;
|
||||||
import io.github.dsheirer.audio.playback.AudioPlaybackManager;
|
import io.github.dsheirer.audio.playback.AudioPlaybackManager;
|
||||||
import io.github.dsheirer.channel.metadata.ChannelMetadataViewer;
|
import io.github.dsheirer.channel.metadata.NowPlayingPanel;
|
||||||
import io.github.dsheirer.controller.channel.ChannelController;
|
import io.github.dsheirer.controller.channel.ChannelController;
|
||||||
import io.github.dsheirer.controller.channel.ChannelModel;
|
import io.github.dsheirer.controller.channel.ChannelModel;
|
||||||
import io.github.dsheirer.controller.channel.ChannelProcessingManager;
|
import io.github.dsheirer.controller.channel.ChannelProcessingManager;
|
||||||
@@ -41,7 +42,6 @@ import io.github.dsheirer.source.tuner.TunerViewPanel;
|
|||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JTable;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
|
||||||
@@ -53,27 +53,18 @@ public class ControllerPanel extends JPanel
|
|||||||
private AudioPanel mAudioPanel;
|
private AudioPanel mAudioPanel;
|
||||||
private BroadcastPanel mBroadcastPanel;
|
private BroadcastPanel mBroadcastPanel;
|
||||||
private ChannelController mChannelController;
|
private ChannelController mChannelController;
|
||||||
private ChannelMetadataViewer mChannelMetadataViewer;
|
private NowPlayingPanel mNowPlayingPanel;
|
||||||
private ChannelModel mChannelModel;
|
private ChannelModel mChannelModel;
|
||||||
private MapPanel mMapPanel;
|
private MapPanel mMapPanel;
|
||||||
private TunerViewPanel mTunerManagerPanel;
|
private TunerViewPanel mTunerManagerPanel;
|
||||||
private BroadcastModel mBroadcastModel;
|
private BroadcastModel mBroadcastModel;
|
||||||
|
|
||||||
private JideTabbedPane mTabbedPane;
|
private JideTabbedPane mTabbedPane;
|
||||||
protected JTable mChannelActivityTable = new JTable();
|
|
||||||
|
|
||||||
public ControllerPanel(AudioPlaybackManager audioPlaybackManager,
|
public ControllerPanel(AudioPlaybackManager audioPlaybackManager, AliasModel aliasModel, BroadcastModel broadcastModel,
|
||||||
AliasModel aliasModel,
|
ChannelModel channelModel, ChannelMapModel channelMapModel, ChannelProcessingManager channelProcessingManager,
|
||||||
BroadcastModel broadcastModel,
|
IconManager iconManager, MapService mapService, SettingsManager settingsManager,
|
||||||
ChannelModel channelModel,
|
SourceManager sourceManager, TunerModel tunerModel, UserPreferences userPreferences)
|
||||||
ChannelMapModel channelMapModel,
|
|
||||||
ChannelProcessingManager channelProcessingManager,
|
|
||||||
IconManager iconManager,
|
|
||||||
MapService mapService,
|
|
||||||
SettingsManager settingsManager,
|
|
||||||
SourceManager sourceManager,
|
|
||||||
TunerModel tunerModel,
|
|
||||||
UserPreferences userPreferences)
|
|
||||||
{
|
{
|
||||||
mBroadcastModel = broadcastModel;
|
mBroadcastModel = broadcastModel;
|
||||||
mChannelModel = channelModel;
|
mChannelModel = channelModel;
|
||||||
@@ -81,19 +72,19 @@ public class ControllerPanel extends JPanel
|
|||||||
mAudioPanel = new AudioPanel(iconManager, userPreferences, settingsManager, sourceManager, audioPlaybackManager,
|
mAudioPanel = new AudioPanel(iconManager, userPreferences, settingsManager, sourceManager, audioPlaybackManager,
|
||||||
aliasModel);
|
aliasModel);
|
||||||
|
|
||||||
mChannelMetadataViewer = new ChannelMetadataViewer(channelModel, channelProcessingManager, iconManager,
|
mNowPlayingPanel = new NowPlayingPanel(channelModel, channelProcessingManager, iconManager,
|
||||||
aliasModel, userPreferences);
|
aliasModel, userPreferences);
|
||||||
|
|
||||||
mMapPanel = new MapPanel(mapService, aliasModel, iconManager, settingsManager);
|
mMapPanel = new MapPanel(mapService, aliasModel, iconManager, settingsManager);
|
||||||
|
|
||||||
mBroadcastPanel = new BroadcastPanel(broadcastModel, aliasModel, iconManager);
|
mBroadcastPanel = new BroadcastPanel(broadcastModel, aliasModel, iconManager, userPreferences);
|
||||||
|
|
||||||
mChannelController = new ChannelController(channelModel, channelProcessingManager, channelMapModel,
|
mChannelController = new ChannelController(channelModel, channelProcessingManager, channelMapModel,
|
||||||
sourceManager, aliasModel);
|
sourceManager, aliasModel, userPreferences);
|
||||||
|
|
||||||
mAliasController = new AliasController(aliasModel, broadcastModel, iconManager);
|
mAliasController = new AliasController(aliasModel, broadcastModel, iconManager, userPreferences);
|
||||||
|
|
||||||
mTunerManagerPanel = new TunerViewPanel(tunerModel);
|
mTunerManagerPanel = new TunerViewPanel(tunerModel, userPreferences);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -108,7 +99,7 @@ public class ControllerPanel extends JPanel
|
|||||||
mTabbedPane = new JideTabbedPane();
|
mTabbedPane = new JideTabbedPane();
|
||||||
mTabbedPane.setFont(this.getFont());
|
mTabbedPane.setFont(this.getFont());
|
||||||
mTabbedPane.setForeground(Color.BLACK);
|
mTabbedPane.setForeground(Color.BLACK);
|
||||||
mTabbedPane.addTab("Now Playing", mChannelMetadataViewer);
|
mTabbedPane.addTab("Now Playing", mNowPlayingPanel);
|
||||||
mTabbedPane.addTab("Aliases", mAliasController);
|
mTabbedPane.addTab("Aliases", mAliasController);
|
||||||
mTabbedPane.addTab("Channels", mChannelController);
|
mTabbedPane.addTab("Channels", mChannelController);
|
||||||
mTabbedPane.addTab("Map", mMapPanel);
|
mTabbedPane.addTab("Map", mMapPanel);
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdr-trunk
|
* ******************************************************************************
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* sdrtrunk
|
||||||
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
|
* it under the terms of the GNU General Public License as published by
|
||||||
* later version.
|
* 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
|
* This program is distributed in the hope that it will be useful,
|
||||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
* 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.
|
* You should have received a copy of the GNU General Public License
|
||||||
* If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.controller.channel;
|
package io.github.dsheirer.controller.channel;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideSplitPane;
|
import com.jidesoft.swing.JideSplitPane;
|
||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
import io.github.dsheirer.controller.channel.map.ChannelMapModel;
|
import io.github.dsheirer.controller.channel.map.ChannelMapModel;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import io.github.dsheirer.source.SourceManager;
|
import io.github.dsheirer.source.SourceManager;
|
||||||
import net.coderazzi.filters.gui.AutoChoices;
|
import net.coderazzi.filters.gui.AutoChoices;
|
||||||
import net.coderazzi.filters.gui.TableFilterHeader;
|
import net.coderazzi.filters.gui.TableFilterHeader;
|
||||||
@@ -43,11 +49,14 @@ public class ChannelController extends JPanel implements ActionListener, ListSel
|
|||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "channel.controller";
|
||||||
private ChannelModel mChannelModel;
|
private ChannelModel mChannelModel;
|
||||||
private ChannelProcessingManager mChannelProcessingManager;
|
private ChannelProcessingManager mChannelProcessingManager;
|
||||||
private JTable mChannelTable;
|
private JTable mChannelTable;
|
||||||
|
private JTableColumnWidthMonitor mColumnWidthMonitor;
|
||||||
private TableFilterHeader mTableFilterHeader;
|
private TableFilterHeader mTableFilterHeader;
|
||||||
private ChannelEditor mEditor;
|
private ChannelEditor mEditor;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
|
||||||
private static final String NEW_CHANNEL = "New";
|
private static final String NEW_CHANNEL = "New";
|
||||||
private static final String COPY_CHANNEL = "Copy";
|
private static final String COPY_CHANNEL = "Copy";
|
||||||
@@ -57,17 +66,16 @@ public class ChannelController extends JPanel implements ActionListener, ListSel
|
|||||||
private JButton mCopyChannelButton = new JButton(COPY_CHANNEL);
|
private JButton mCopyChannelButton = new JButton(COPY_CHANNEL);
|
||||||
private JButton mDeleteChannelButton = new JButton(DELETE_CHANNEL);
|
private JButton mDeleteChannelButton = new JButton(DELETE_CHANNEL);
|
||||||
|
|
||||||
public ChannelController(ChannelModel channelModel,
|
public ChannelController(ChannelModel channelModel, ChannelProcessingManager channelProcessingManager,
|
||||||
ChannelProcessingManager channelProcessingManager,
|
ChannelMapModel channelMapModel, SourceManager sourceManager, AliasModel aliasModel,
|
||||||
ChannelMapModel channelMapModel,
|
UserPreferences userPreferences)
|
||||||
SourceManager sourceManager,
|
|
||||||
AliasModel aliasModel)
|
|
||||||
{
|
{
|
||||||
mChannelModel = channelModel;
|
mChannelModel = channelModel;
|
||||||
mChannelProcessingManager = channelProcessingManager;
|
mChannelProcessingManager = channelProcessingManager;
|
||||||
mEditor = new ChannelEditor(channelModel, channelProcessingManager, channelMapModel, sourceManager, aliasModel);
|
mEditor = new ChannelEditor(channelModel, channelProcessingManager, channelMapModel, sourceManager, aliasModel);
|
||||||
mChannelModel.addListener(mEditor);
|
mChannelModel.addListener(mEditor);
|
||||||
mChannelProcessingManager.addChannelEventListener(mEditor);
|
mChannelProcessingManager.addChannelEventListener(mEditor);
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -82,6 +90,7 @@ public class ChannelController extends JPanel implements ActionListener, ListSel
|
|||||||
mChannelTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
mChannelTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
mChannelTable.getSelectionModel().addListSelectionListener(this);
|
mChannelTable.getSelectionModel().addListSelectionListener(this);
|
||||||
mChannelTable.setAutoCreateRowSorter(true);
|
mChannelTable.setAutoCreateRowSorter(true);
|
||||||
|
mColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mChannelTable, TABLE_PREFERENCE_KEY);
|
||||||
|
|
||||||
mTableFilterHeader = new TableFilterHeader(mChannelTable, AutoChoices.ENABLED);
|
mTableFilterHeader = new TableFilterHeader(mChannelTable, AutoChoices.ENABLED);
|
||||||
mTableFilterHeader.setFilterOnUpdates(true);
|
mTableFilterHeader.setFilterOnUpdates(true);
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ import java.awt.AWTException;
|
|||||||
import java.awt.Desktop;
|
import java.awt.Desktop;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.Point;
|
||||||
import java.awt.Robot;
|
import java.awt.Robot;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
@@ -97,8 +98,12 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
private final static Logger mLog = LoggerFactory.getLogger(SDRTrunk.class);
|
private final static Logger mLog = LoggerFactory.getLogger(SDRTrunk.class);
|
||||||
|
|
||||||
private static final String PROPERTY_BROADCAST_STATUS_VISIBLE = "main.broadcast.status.visible";
|
private static final String PROPERTY_BROADCAST_STATUS_VISIBLE = "main.broadcast.status.visible";
|
||||||
private boolean mBroadcastStatusVisible;
|
private static final String BASE_WINDOW_NAME = "sdrtrunk.main.window";
|
||||||
|
private static final String CONTROLLER_PANEL_IDENTIFIER = BASE_WINDOW_NAME + ".control.panel";
|
||||||
|
private static final String SPECTRAL_PANEL_IDENTIFIER = BASE_WINDOW_NAME + ".spectral.panel";
|
||||||
|
private static final String WINDOW_FRAME_IDENTIFIER = BASE_WINDOW_NAME + ".frame";
|
||||||
|
|
||||||
|
private boolean mBroadcastStatusVisible;
|
||||||
private AudioPacketManager mAudioPacketManager;
|
private AudioPacketManager mAudioPacketManager;
|
||||||
private IconManager mIconManager;
|
private IconManager mIconManager;
|
||||||
private BroadcastStatusPanel mBroadcastStatusPanel;
|
private BroadcastStatusPanel mBroadcastStatusPanel;
|
||||||
@@ -271,15 +276,45 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
*/
|
*/
|
||||||
mTitle = SystemProperties.getInstance().getApplicationName();
|
mTitle = SystemProperties.getInstance().getApplicationName();
|
||||||
mMainGui.setTitle(mTitle);
|
mMainGui.setTitle(mTitle);
|
||||||
mMainGui.setSize(new Dimension(1280, 800));
|
|
||||||
mMainGui.setLocationRelativeTo(null);
|
Point location = mUserPreferences.getSwingPreference().getLocation(WINDOW_FRAME_IDENTIFIER);
|
||||||
|
if(location != null)
|
||||||
|
{
|
||||||
|
mMainGui.setLocation(location);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMainGui.setLocationRelativeTo(null);
|
||||||
|
}
|
||||||
mMainGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
mMainGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
mMainGui.addWindowListener(new ShutdownMonitor());
|
mMainGui.addWindowListener(new ShutdownMonitor());
|
||||||
|
|
||||||
//Set preferred sizes to influence the split
|
Dimension dimension = mUserPreferences.getSwingPreference().getDimension(WINDOW_FRAME_IDENTIFIER);
|
||||||
|
|
||||||
mSpectralPanel.setPreferredSize(new Dimension(1280, 300));
|
mSpectralPanel.setPreferredSize(new Dimension(1280, 300));
|
||||||
mControllerPanel.setPreferredSize(new Dimension(1280, 500));
|
mControllerPanel.setPreferredSize(new Dimension(1280, 500));
|
||||||
|
|
||||||
|
if(dimension != null)
|
||||||
|
{
|
||||||
|
Dimension spectral = mUserPreferences.getSwingPreference().getDimension(SPECTRAL_PANEL_IDENTIFIER);
|
||||||
|
if(spectral != null)
|
||||||
|
{
|
||||||
|
mSpectralPanel.setSize(spectral);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dimension controller = mUserPreferences.getSwingPreference().getDimension(CONTROLLER_PANEL_IDENTIFIER);
|
||||||
|
if(controller != null)
|
||||||
|
{
|
||||||
|
mControllerPanel.setSize(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
mMainGui.setSize(dimension);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMainGui.setSize(new Dimension(1280, 800));
|
||||||
|
}
|
||||||
|
|
||||||
mSplitPane = new JideSplitPane(JideSplitPane.VERTICAL_SPLIT);
|
mSplitPane = new JideSplitPane(JideSplitPane.VERTICAL_SPLIT);
|
||||||
mSplitPane.setDividerSize(5);
|
mSplitPane.setDividerSize(5);
|
||||||
mSplitPane.add(mSpectralPanel);
|
mSplitPane.add(mSpectralPanel);
|
||||||
@@ -424,6 +459,10 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
private void processShutdown()
|
private void processShutdown()
|
||||||
{
|
{
|
||||||
mLog.info("Application shutdown started ...");
|
mLog.info("Application shutdown started ...");
|
||||||
|
mUserPreferences.getSwingPreference().setLocation(WINDOW_FRAME_IDENTIFIER, mMainGui.getLocation());
|
||||||
|
mUserPreferences.getSwingPreference().setDimension(WINDOW_FRAME_IDENTIFIER, mMainGui.getSize());
|
||||||
|
mUserPreferences.getSwingPreference().setDimension(SPECTRAL_PANEL_IDENTIFIER, mSpectralPanel.getSize());
|
||||||
|
mUserPreferences.getSwingPreference().setDimension(CONTROLLER_PANEL_IDENTIFIER, mControllerPanel.getSize());
|
||||||
mJavaFxWindowManager.shutdown();
|
mJavaFxWindowManager.shutdown();
|
||||||
mLog.info("Stopping channels ...");
|
mLog.info("Stopping channels ...");
|
||||||
mChannelProcessingManager.shutdown();
|
mChannelProcessingManager.shutdown();
|
||||||
@@ -443,7 +482,8 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
{
|
{
|
||||||
if(mBroadcastStatusPanel == null)
|
if(mBroadcastStatusPanel == null)
|
||||||
{
|
{
|
||||||
mBroadcastStatusPanel = new BroadcastStatusPanel(mBroadcastModel);
|
mBroadcastStatusPanel = new BroadcastStatusPanel(mBroadcastModel, mUserPreferences,
|
||||||
|
"application.broadcast.status.panel");
|
||||||
mBroadcastStatusPanel.setPreferredSize(new Dimension(880, 70));
|
mBroadcastStatusPanel.setPreferredSize(new Dimension(880, 70));
|
||||||
mBroadcastStatusPanel.getTable().setEnabled(false);
|
mBroadcastStatusPanel.getTable().setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -84,7 +84,7 @@ public class IdentifierCollection
|
|||||||
return mUpdated;
|
return mUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setUpdated(boolean updated)
|
public void setUpdated(boolean updated)
|
||||||
{
|
{
|
||||||
mUpdated = updated;
|
mUpdated = updated;
|
||||||
}
|
}
|
||||||
@@ -114,6 +114,14 @@ public class IdentifierCollection
|
|||||||
return Collections.unmodifiableList(mIdentifiers);
|
return Collections.unmodifiableList(mIdentifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this collection has no identifiers
|
||||||
|
*/
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return mIdentifiers.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of identifiers by identifier class from this collection.
|
* Get a list of identifiers by identifier class from this collection.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ package io.github.dsheirer.identifier;
|
|||||||
|
|
||||||
import io.github.dsheirer.identifier.configuration.AliasListConfigurationIdentifier;
|
import io.github.dsheirer.identifier.configuration.AliasListConfigurationIdentifier;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -32,6 +34,7 @@ import java.util.Iterator;
|
|||||||
public class MutableIdentifierCollection extends IdentifierCollection implements IdentifierUpdateProvider,
|
public class MutableIdentifierCollection extends IdentifierCollection implements IdentifierUpdateProvider,
|
||||||
Listener<IdentifierUpdateNotification>
|
Listener<IdentifierUpdateNotification>
|
||||||
{
|
{
|
||||||
|
private final static Logger mLog = LoggerFactory.getLogger(MutableIdentifierCollection.class);
|
||||||
private Listener<IdentifierUpdateNotification> mListener;
|
private Listener<IdentifierUpdateNotification> mListener;
|
||||||
|
|
||||||
public MutableIdentifierCollection()
|
public MutableIdentifierCollection()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,7 +23,6 @@ package io.github.dsheirer.identifier.patch;
|
|||||||
import io.github.dsheirer.identifier.Identifier;
|
import io.github.dsheirer.identifier.Identifier;
|
||||||
import io.github.dsheirer.identifier.IdentifierClass;
|
import io.github.dsheirer.identifier.IdentifierClass;
|
||||||
import io.github.dsheirer.identifier.Role;
|
import io.github.dsheirer.identifier.Role;
|
||||||
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -32,6 +31,14 @@ import java.util.Map;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for (temporary) patch groups and related identifiers.
|
* Manager for (temporary) patch groups and related identifiers.
|
||||||
|
*
|
||||||
|
* Patch groups are primarily used on Motorola P25 systems. This manager monitors patch group additions and deletions
|
||||||
|
* and maintains a map of the current patch groups.
|
||||||
|
*
|
||||||
|
* Traffic channel calls will sometimes reference a patch group by simply using the patch group identifier. This
|
||||||
|
* manager will replace that reference with the full patch group so that the call event has the full patch group
|
||||||
|
* including all of the patched groups, which may not have been included in the patch group reference on the
|
||||||
|
* traffic channel.
|
||||||
*/
|
*/
|
||||||
public class PatchGroupManager
|
public class PatchGroupManager
|
||||||
{
|
{
|
||||||
@@ -127,7 +134,7 @@ public class PatchGroupManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the TALKGROUP or PATCH GROUP identifier and replaces the identifier with the current patch group
|
* Checks the PATCH GROUP identifier and replaces the identifier with the current patch group
|
||||||
* if the identifier matches a currently managed patch group.
|
* if the identifier matches a currently managed patch group.
|
||||||
*
|
*
|
||||||
* @param identifier for a talkgroup or a patch group.
|
* @param identifier for a talkgroup or a patch group.
|
||||||
@@ -144,22 +151,6 @@ public class PatchGroupManager
|
|||||||
{
|
{
|
||||||
switch(identifier.getForm())
|
switch(identifier.getForm())
|
||||||
{
|
{
|
||||||
case TALKGROUP:
|
|
||||||
if(identifier instanceof TalkgroupIdentifier)
|
|
||||||
{
|
|
||||||
TalkgroupIdentifier tgi = (TalkgroupIdentifier)identifier;
|
|
||||||
|
|
||||||
if(tgi.isGroup())
|
|
||||||
{
|
|
||||||
int talkgroupId = ((TalkgroupIdentifier)identifier).getValue();
|
|
||||||
|
|
||||||
if(mPatchGroupMap.containsKey(talkgroupId))
|
|
||||||
{
|
|
||||||
return mPatchGroupMap.get(talkgroupId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PATCH_GROUP:
|
case PATCH_GROUP:
|
||||||
if(identifier instanceof PatchGroupIdentifier)
|
if(identifier instanceof PatchGroupIdentifier)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -34,6 +34,7 @@ import io.github.dsheirer.identifier.Role;
|
|||||||
import io.github.dsheirer.module.ProcessingChain;
|
import io.github.dsheirer.module.ProcessingChain;
|
||||||
import io.github.dsheirer.preference.PreferenceType;
|
import io.github.dsheirer.preference.PreferenceType;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -55,10 +56,12 @@ import java.util.List;
|
|||||||
|
|
||||||
public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain>
|
public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain>
|
||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(DecodeEventPanel.class);
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
private final static Logger mLog = LoggerFactory.getLogger(DecodeEventPanel.class);
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "decode.event.panel";
|
||||||
|
|
||||||
private JTable mTable;
|
private JTable mTable;
|
||||||
|
private JTableColumnWidthMonitor mTableColumnWidthMonitor;
|
||||||
private DecodeEventModel mEmptyDecodeEventModel;
|
private DecodeEventModel mEmptyDecodeEventModel;
|
||||||
private JScrollPane mEmptyScroller;
|
private JScrollPane mEmptyScroller;
|
||||||
private IconManager mIconManager;
|
private IconManager mIconManager;
|
||||||
@@ -83,6 +86,7 @@ public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain
|
|||||||
mTable = new JTable(mEmptyDecodeEventModel);
|
mTable = new JTable(mEmptyDecodeEventModel);
|
||||||
mTable.setAutoCreateRowSorter(true);
|
mTable.setAutoCreateRowSorter(true);
|
||||||
mTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
|
mTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
|
||||||
|
mTableColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, TABLE_PREFERENCE_KEY);
|
||||||
updateCellRenderers();
|
updateCellRenderers();
|
||||||
|
|
||||||
mEmptyScroller = new JScrollPane(mTable);
|
mEmptyScroller = new JScrollPane(mTable);
|
||||||
@@ -127,12 +131,17 @@ public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain
|
|||||||
public void receive(ProcessingChain processingChain)
|
public void receive(ProcessingChain processingChain)
|
||||||
{
|
{
|
||||||
EventQueue.invokeLater(() -> {
|
EventQueue.invokeLater(() -> {
|
||||||
|
|
||||||
|
//Dispose the current column width monitor and recreate after we swap out the table model
|
||||||
|
mTableColumnWidthMonitor.dispose();
|
||||||
mTable.setModel(processingChain != null ? processingChain.getDecodeEventModel() : mEmptyDecodeEventModel);
|
mTable.setModel(processingChain != null ? processingChain.getDecodeEventModel() : mEmptyDecodeEventModel);
|
||||||
|
|
||||||
if(processingChain != null)
|
if(processingChain != null)
|
||||||
{
|
{
|
||||||
updateCellRenderers();
|
updateCellRenderers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTableColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, TABLE_PREFERENCE_KEY);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,17 +171,6 @@ public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain
|
|||||||
if(value instanceof IdentifierCollection)
|
if(value instanceof IdentifierCollection)
|
||||||
{
|
{
|
||||||
List<Identifier> identifiers = ((IdentifierCollection)value).getIdentifiers(mRole);
|
List<Identifier> identifiers = ((IdentifierCollection)value).getIdentifiers(mRole);
|
||||||
|
|
||||||
// if(identifiers.size() > 1)
|
|
||||||
// {
|
|
||||||
// StringBuilder sb = new StringBuilder();
|
|
||||||
// sb.append("Multiple Identifiers:\n");
|
|
||||||
// for(Identifier identifier: identifiers)
|
|
||||||
// {
|
|
||||||
// sb.append("ID:").append(identifier.debug()).append("\n");
|
|
||||||
// }
|
|
||||||
// mLog.debug(sb.toString());
|
|
||||||
// }
|
|
||||||
label.setText(format(identifiers));
|
label.setText(format(identifiers));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,17 +15,18 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.module.decode.event;
|
package io.github.dsheirer.module.decode.event;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideButton;
|
import com.jidesoft.swing.JideButton;
|
||||||
import com.jidesoft.swing.JideSplitButton;
|
import com.jidesoft.swing.JideSplitButton;
|
||||||
import io.github.dsheirer.controller.channel.ChannelProcessingManager;
|
|
||||||
import io.github.dsheirer.filter.FilterEditorPanel;
|
import io.github.dsheirer.filter.FilterEditorPanel;
|
||||||
import io.github.dsheirer.filter.FilterSet;
|
import io.github.dsheirer.filter.FilterSet;
|
||||||
import io.github.dsheirer.message.IMessage;
|
import io.github.dsheirer.message.IMessage;
|
||||||
import io.github.dsheirer.module.ProcessingChain;
|
import io.github.dsheirer.module.ProcessingChain;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -49,26 +51,24 @@ import java.awt.event.MouseListener;
|
|||||||
public class MessageActivityPanel extends JPanel implements Listener<ProcessingChain>
|
public class MessageActivityPanel extends JPanel implements Listener<ProcessingChain>
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(MessageActivityPanel.class);
|
private final static Logger mLog = LoggerFactory.getLogger(MessageActivityPanel.class);
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "message.activity.panel";
|
||||||
private static MessageActivityModel EMPTY_MODEL = new MessageActivityModel();
|
private static MessageActivityModel EMPTY_MODEL = new MessageActivityModel();
|
||||||
|
|
||||||
private JTable mTable = new JTable(EMPTY_MODEL);
|
private JTable mTable = new JTable(EMPTY_MODEL);
|
||||||
|
private JTableColumnWidthMonitor mTableColumnWidthMonitor;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
private MessageManagementPanel mManagementPanel = new MessageManagementPanel();
|
private MessageManagementPanel mManagementPanel = new MessageManagementPanel();
|
||||||
|
|
||||||
private ChannelProcessingManager mChannelProcessingManager;
|
public MessageActivityPanel(UserPreferences userPreferences)
|
||||||
|
|
||||||
public MessageActivityPanel(ChannelProcessingManager channelProcessingManager)
|
|
||||||
{
|
{
|
||||||
mChannelProcessingManager = channelProcessingManager;
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[][grow,fill]", "[]0[grow,fill]"));
|
setLayout(new MigLayout("insets 0 0 0 0", "[][grow,fill]", "[]0[grow,fill]"));
|
||||||
|
|
||||||
add(mManagementPanel, "span,growx");
|
add(mManagementPanel, "span,growx");
|
||||||
|
|
||||||
add(new JScrollPane(mTable), "span,grow");
|
add(new JScrollPane(mTable), "span,grow");
|
||||||
|
mTableColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, TABLE_PREFERENCE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -79,6 +79,8 @@ public class MessageActivityPanel extends JPanel implements Listener<ProcessingC
|
|||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
|
//Remove the existing table column width monitor and replace after swapping the table model
|
||||||
|
mTableColumnWidthMonitor.dispose();
|
||||||
mTable.setModel(processingChain != null ? processingChain.getMessageActivityModel() : EMPTY_MODEL);
|
mTable.setModel(processingChain != null ? processingChain.getMessageActivityModel() : EMPTY_MODEL);
|
||||||
|
|
||||||
mTable.getColumnModel().getColumn(0).setPreferredWidth(18);
|
mTable.getColumnModel().getColumn(0).setPreferredWidth(18);
|
||||||
@@ -93,6 +95,7 @@ public class MessageActivityPanel extends JPanel implements Listener<ProcessingC
|
|||||||
{
|
{
|
||||||
mManagementPanel.disableButtons();
|
mManagementPanel.disableButtons();
|
||||||
}
|
}
|
||||||
|
mTableColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, TABLE_PREFERENCE_KEY);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -33,8 +33,6 @@ import io.github.dsheirer.module.decode.p25.message.pdu.packet.sndcp.SNDCPPacket
|
|||||||
import io.github.dsheirer.module.decode.p25.reference.DataUnitID;
|
import io.github.dsheirer.module.decode.p25.reference.DataUnitID;
|
||||||
import io.github.dsheirer.module.decode.p25.reference.IPHeaderCompression;
|
import io.github.dsheirer.module.decode.p25.reference.IPHeaderCompression;
|
||||||
import io.github.dsheirer.module.decode.p25.reference.UDPHeaderCompression;
|
import io.github.dsheirer.module.decode.p25.reference.UDPHeaderCompression;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -44,7 +42,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class PacketMessage extends P25Message
|
public class PacketMessage extends P25Message
|
||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(PacketMessage.class);
|
// private final static Logger mLog = LoggerFactory.getLogger(PacketMessage.class);
|
||||||
|
|
||||||
private PDUSequence mPDUSequence;
|
private PDUSequence mPDUSequence;
|
||||||
private BinaryMessage mPayload;
|
private BinaryMessage mPayload;
|
||||||
@@ -88,7 +86,6 @@ public class PacketMessage extends P25Message
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mLog.debug("***************** 2 byte SNDCP header with no data blocks header: " + getPDUSequence().getHeader().getMessage().toHexString());
|
|
||||||
mSNDCPPacketHeader = new SNDCPPacketHeader(getHeader().isOutbound());
|
mSNDCPPacketHeader = new SNDCPPacketHeader(getHeader().isOutbound());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,7 +159,7 @@ public class PacketMessage extends P25Message
|
|||||||
{
|
{
|
||||||
List<Integer> numbers = new ArrayList<>();
|
List<Integer> numbers = new ArrayList<>();
|
||||||
|
|
||||||
for(DataBlock dataBlock: getPDUSequence().getDataBlocks())
|
for(DataBlock dataBlock : getPDUSequence().getDataBlocks())
|
||||||
{
|
{
|
||||||
if(dataBlock instanceof ConfirmedDataBlock)
|
if(dataBlock instanceof ConfirmedDataBlock)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import io.github.dsheirer.preference.identifier.TalkgroupFormatPreference;
|
|||||||
import io.github.dsheirer.preference.playlist.PlaylistPreference;
|
import io.github.dsheirer.preference.playlist.PlaylistPreference;
|
||||||
import io.github.dsheirer.preference.source.ChannelMultiFrequencyPreference;
|
import io.github.dsheirer.preference.source.ChannelMultiFrequencyPreference;
|
||||||
import io.github.dsheirer.preference.source.TunerPreference;
|
import io.github.dsheirer.preference.source.TunerPreference;
|
||||||
|
import io.github.dsheirer.preference.swing.SwingPreference;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,6 +56,7 @@ public class UserPreferences implements Listener<PreferenceType>
|
|||||||
private PlaylistPreference mPlaylistPreference;
|
private PlaylistPreference mPlaylistPreference;
|
||||||
private TalkgroupFormatPreference mTalkgroupFormatPreference;
|
private TalkgroupFormatPreference mTalkgroupFormatPreference;
|
||||||
private TunerPreference mTunerPreference;
|
private TunerPreference mTunerPreference;
|
||||||
|
private SwingPreference mSwingPreference = new SwingPreference();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new user preferences instance
|
* Constructs a new user preferences instance
|
||||||
@@ -120,6 +122,15 @@ public class UserPreferences implements Listener<PreferenceType>
|
|||||||
return mTunerPreference;
|
return mTunerPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swing window location/size user preferences
|
||||||
|
*/
|
||||||
|
public SwingPreference getSwingPreference()
|
||||||
|
{
|
||||||
|
return mSwingPreference;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the managed preferences
|
* Loads the managed preferences
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -42,6 +42,7 @@ public class APCO25TalkgroupFormatter extends IntegerFormatter
|
|||||||
switch(format)
|
switch(format)
|
||||||
{
|
{
|
||||||
case DECIMAL:
|
case DECIMAL:
|
||||||
|
case FORMATTED:
|
||||||
return toDecimal(identifier.getValue(),
|
return toDecimal(identifier.getValue(),
|
||||||
(identifier.isGroup() ? GROUP_DECIMAL_WIDTH : UNIT_DECIMAL_WIDTH));
|
(identifier.isGroup() ? GROUP_DECIMAL_WIDTH : UNIT_DECIMAL_WIDTH));
|
||||||
case HEXADECIMAL:
|
case HEXADECIMAL:
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class MDC1200TalkgroupFormatter extends IntegerFormatter
|
|||||||
switch(format)
|
switch(format)
|
||||||
{
|
{
|
||||||
case DECIMAL:
|
case DECIMAL:
|
||||||
|
case FORMATTED:
|
||||||
return toDecimal(identifier.getValue(), DECIMAL_WIDTH);
|
return toDecimal(identifier.getValue(), DECIMAL_WIDTH);
|
||||||
case HEXADECIMAL:
|
case HEXADECIMAL:
|
||||||
return toHex(identifier.getValue(), HEXADECIMAL_WIDTH);
|
return toHex(identifier.getValue(), HEXADECIMAL_WIDTH);
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class PassportTalkgroupFormatter extends IntegerFormatter
|
|||||||
switch(format)
|
switch(format)
|
||||||
{
|
{
|
||||||
case DECIMAL:
|
case DECIMAL:
|
||||||
|
case FORMATTED:
|
||||||
return toDecimal(identifier.getValue(), DECIMAL_WIDTH);
|
return toDecimal(identifier.getValue(), DECIMAL_WIDTH);
|
||||||
case HEXADECIMAL:
|
case HEXADECIMAL:
|
||||||
return toHex(identifier.getValue(), HEXADECIMAL_WIDTH);
|
return toHex(identifier.getValue(), HEXADECIMAL_WIDTH);
|
||||||
|
|||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
|
* sdrtrunk
|
||||||
|
* Copyright (C) 2014-2019 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.preference.swing;
|
||||||
|
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.util.ThreadPool;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ListSelectionEvent;
|
||||||
|
import javax.swing.event.TableColumnModelEvent;
|
||||||
|
import javax.swing.event.TableColumnModelListener;
|
||||||
|
import javax.swing.table.TableColumnModel;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitors a JTable column model and persists column width changes to the user preferences. Restores
|
||||||
|
* previous column width preferred sizes on application restart.
|
||||||
|
*/
|
||||||
|
public class JTableColumnWidthMonitor
|
||||||
|
{
|
||||||
|
private static final Logger mLog = LoggerFactory.getLogger(JTableColumnWidthMonitor.class);
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
private JTable mTable;
|
||||||
|
private String mKey;
|
||||||
|
private ColumnResizeListener mColumnResizeListener = new ColumnResizeListener();
|
||||||
|
private AtomicBoolean mSaveInProgress = new AtomicBoolean();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a column width monitor.
|
||||||
|
*
|
||||||
|
* @param userPreferences to store column widths
|
||||||
|
* @param table to monitor for column width changes
|
||||||
|
* @param key that uniquely identifies the table to monitor
|
||||||
|
*/
|
||||||
|
public JTableColumnWidthMonitor(UserPreferences userPreferences, JTable table, String key)
|
||||||
|
{
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
mTable = table;
|
||||||
|
mKey = key;
|
||||||
|
|
||||||
|
restoreColumnWidths();
|
||||||
|
mTable.getColumnModel().addColumnModelListener(mColumnResizeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares this monitor for disposal by unregistering as a listener to the table column model.
|
||||||
|
*/
|
||||||
|
public void dispose()
|
||||||
|
{
|
||||||
|
if(mTable != null && mColumnResizeListener != null)
|
||||||
|
{
|
||||||
|
mTable.getColumnModel().removeColumnModelListener(mColumnResizeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
mTable = null;
|
||||||
|
mUserPreferences = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preferred column widths on the table from persisted settings
|
||||||
|
*/
|
||||||
|
private void restoreColumnWidths()
|
||||||
|
{
|
||||||
|
TableColumnModel model = mTable.getColumnModel();
|
||||||
|
|
||||||
|
for(int x = 0; x < model.getColumnCount(); x++)
|
||||||
|
{
|
||||||
|
int width = mUserPreferences.getSwingPreference().getInt(getColumnKey(x), Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
if(width != Integer.MAX_VALUE)
|
||||||
|
{
|
||||||
|
model.getColumn(x).setPreferredWidth(width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the current column widths to the user preferences
|
||||||
|
*/
|
||||||
|
private void storeColumnWidths()
|
||||||
|
{
|
||||||
|
TableColumnModel model = mTable.getColumnModel();
|
||||||
|
|
||||||
|
for(int x = 0; x < model.getColumnCount(); x++)
|
||||||
|
{
|
||||||
|
mUserPreferences.getSwingPreference().setInt(getColumnKey(x), model.getColumn(x).getWidth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a preference key for the column number
|
||||||
|
*/
|
||||||
|
private String getColumnKey(int column)
|
||||||
|
{
|
||||||
|
return mKey + ".column." + column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table column model listener.
|
||||||
|
*/
|
||||||
|
class ColumnResizeListener implements TableColumnModelListener
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void columnMarginChanged(ChangeEvent e)
|
||||||
|
{
|
||||||
|
if(mSaveInProgress.compareAndSet(false, true))
|
||||||
|
{
|
||||||
|
ThreadPool.SCHEDULED.schedule(new ColumnWidthSaveTask(), 2, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void columnAdded(TableColumnModelEvent e){}
|
||||||
|
@Override
|
||||||
|
public void columnRemoved(TableColumnModelEvent e){}
|
||||||
|
@Override
|
||||||
|
public void columnMoved(TableColumnModelEvent e){}
|
||||||
|
@Override
|
||||||
|
public void columnSelectionChanged(ListSelectionEvent e){}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ColumnWidthSaveTask implements Runnable
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
storeColumnWidths();
|
||||||
|
mSaveInProgress.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
|
* sdrtrunk
|
||||||
|
* Copyright (C) 2014-2019 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.preference.swing;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GraphicsDevice;
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User preference settings for Swing windows and components.
|
||||||
|
*/
|
||||||
|
public class SwingPreference
|
||||||
|
{
|
||||||
|
private static final Logger mLog = LoggerFactory.getLogger(SwingPreference.class);
|
||||||
|
|
||||||
|
private static final String LOCATION_X = ".x";
|
||||||
|
private static final String LOCATION_Y = ".y";
|
||||||
|
private static final String SIZE_HEIGHT = ".height";
|
||||||
|
private static final String SIZE_WIDTH = ".width";
|
||||||
|
|
||||||
|
private Preferences mPreferences = Preferences.userNodeForPackage(SwingPreference.class);
|
||||||
|
|
||||||
|
public SwingPreference()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the stored swing related integer value
|
||||||
|
* @param key for accessing the value
|
||||||
|
* @param defaultValue to return if the value has not yet been persisted
|
||||||
|
* @return value or default value
|
||||||
|
*/
|
||||||
|
public int getInt(String key, int defaultValue)
|
||||||
|
{
|
||||||
|
return mPreferences.getInt(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the swing related integer value
|
||||||
|
* @param key to reference the value
|
||||||
|
*/
|
||||||
|
public void setInt(String key, int value)
|
||||||
|
{
|
||||||
|
mPreferences.putInt(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the persisted window location for the specified preference key.
|
||||||
|
* @param key identifying the window
|
||||||
|
* @return location or null
|
||||||
|
*/
|
||||||
|
public Point getLocation(String key)
|
||||||
|
{
|
||||||
|
int x = mPreferences.getInt(key + LOCATION_X, Integer.MAX_VALUE);
|
||||||
|
int y = mPreferences.getInt(key + LOCATION_Y, Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
if(x != Integer.MAX_VALUE && y != Integer.MAX_VALUE)
|
||||||
|
{
|
||||||
|
Point location = new Point(x,y);
|
||||||
|
|
||||||
|
if(isValidWindowLocation(location))
|
||||||
|
{
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the current window location
|
||||||
|
* @param key to identify the window
|
||||||
|
* @param location to persist
|
||||||
|
*/
|
||||||
|
public void setLocation(String key, Point location)
|
||||||
|
{
|
||||||
|
mPreferences.putInt(key + LOCATION_X, location.x);
|
||||||
|
mPreferences.putInt(key + LOCATION_Y, location.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the stored size/dimension of the window identified by the key argument.
|
||||||
|
* @param key to identify the window
|
||||||
|
* @return dimension or null
|
||||||
|
*/
|
||||||
|
public Dimension getDimension(String key)
|
||||||
|
{
|
||||||
|
int height = mPreferences.getInt(key + SIZE_HEIGHT, Integer.MAX_VALUE);
|
||||||
|
int width = mPreferences.getInt(key + SIZE_WIDTH, Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
if(height != Integer.MAX_VALUE && width != Integer.MAX_VALUE)
|
||||||
|
{
|
||||||
|
return new Dimension(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDimension(String key, Dimension dimension)
|
||||||
|
{
|
||||||
|
mPreferences.putInt(key + SIZE_HEIGHT, dimension.height);
|
||||||
|
mPreferences.putInt(key + SIZE_WIDTH, dimension.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests a stored window location to determine if it can be displayed on the currently available
|
||||||
|
* graphics display devices so that we don't position a window at a previously available location
|
||||||
|
* that is not currently available.
|
||||||
|
*
|
||||||
|
* @param location to test
|
||||||
|
* @return true if the location is displayable.
|
||||||
|
*/
|
||||||
|
private boolean isValidWindowLocation(Point location)
|
||||||
|
{
|
||||||
|
for(GraphicsDevice gd:GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices())
|
||||||
|
{
|
||||||
|
if(gd.getDefaultConfiguration().getBounds().contains(location))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,28 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* SDR Trunk
|
* ******************************************************************************
|
||||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
* sdrtrunk
|
||||||
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
******************************************************************************/
|
* *****************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
package io.github.dsheirer.source.tuner;
|
package io.github.dsheirer.source.tuner;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideSplitPane;
|
import com.jidesoft.swing.JideSplitPane;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import io.github.dsheirer.source.tuner.TunerEvent.Event;
|
import io.github.dsheirer.source.tuner.TunerEvent.Event;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
@@ -49,17 +53,21 @@ public class TunerViewPanel extends JPanel
|
|||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(TunerViewPanel.class);
|
private final static Logger mLog = LoggerFactory.getLogger(TunerViewPanel.class);
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "tuner.view.panel";
|
||||||
|
|
||||||
private TunerModel mTunerModel;
|
private TunerModel mTunerModel;
|
||||||
private JTable mTunerTable;
|
private JTable mTunerTable;
|
||||||
|
private JTableColumnWidthMonitor mColumnWidthMonitor;
|
||||||
private TableRowSorter<TunerModel> mRowSorter;
|
private TableRowSorter<TunerModel> mRowSorter;
|
||||||
private JideSplitPane mSplitPane;
|
private JideSplitPane mSplitPane;
|
||||||
private TunerEditor mTunerEditor;
|
private TunerEditor mTunerEditor;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
|
||||||
public TunerViewPanel(TunerModel tunerModel)
|
public TunerViewPanel(TunerModel tunerModel, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mTunerModel = tunerModel;
|
mTunerModel = tunerModel;
|
||||||
mTunerEditor = new TunerEditor(mTunerModel.getTunerConfigurationModel());
|
mTunerEditor = new TunerEditor(mTunerModel.getTunerConfigurationModel());
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -149,6 +157,7 @@ public class TunerViewPanel extends JPanel
|
|||||||
TableCellRenderer renderer = new LinkCellRenderer();
|
TableCellRenderer renderer = new LinkCellRenderer();
|
||||||
mTunerTable.getColumnModel().getColumn(TunerModel.SPECTRAL_DISPLAY_NEW).setCellRenderer(renderer);
|
mTunerTable.getColumnModel().getColumn(TunerModel.SPECTRAL_DISPLAY_NEW).setCellRenderer(renderer);
|
||||||
|
|
||||||
|
mColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTunerTable, TABLE_PREFERENCE_KEY);
|
||||||
JScrollPane listScroller = new JScrollPane(mTunerTable);
|
JScrollPane listScroller = new JScrollPane(mTunerTable);
|
||||||
listScroller.setPreferredSize(new Dimension(400, 20));
|
listScroller.setPreferredSize(new Dimension(400, 20));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user