Added settings file, and displaying playlists as tables

This commit is contained in:
Andrew Lalis 2017-07-23 11:28:15 +02:00 committed by Andrew Lalis
parent 117254e27d
commit 4a44675e8e
8 changed files with 208 additions and 45 deletions

View File

@ -17,9 +17,7 @@ import sx.blah.discord.handle.obj.Permissions;
import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.DiscordException;
import sx.blah.discord.util.RateLimitException; import sx.blah.discord.util.RateLimitException;
import java.io.BufferedReader; import java.io.*;
import java.io.FileReader;
import java.io.IOException;
import java.util.*; import java.util.*;
/** /**
@ -32,6 +30,7 @@ public class HandieBot {
//Application name is the name of application as it appears on display window. //Application name is the name of application as it appears on display window.
public static final String APPLICATION_NAME = "HandieBot"; public static final String APPLICATION_NAME = "HandieBot";
//The token required for logging into Discord. This is secure and must not be in the source code on GitHub. //The token required for logging into Discord. This is secure and must not be in the source code on GitHub.
private static final String TOKEN; private static final String TOKEN;
static { static {
@ -43,8 +42,22 @@ public class HandieBot {
} }
//Variable to enable or disable GUI. //Variable to enable or disable GUI.
private static boolean USE_GUI = true; private static boolean USE_GUI = true;
//Settings for the bot. Tries to load the settings, or if that doesn't work, it will load defaults.
public static Properties settings;
static{
try {
Properties defaultSettings = new Properties();
defaultSettings.load(HandieBot.class.getClassLoader().getResourceAsStream("default_settings"));
settings = new Properties(defaultSettings);
settings.load(new FileInputStream(FileUtil.getDataDirectory()+"settings"));
} catch (IOException e) {
e.printStackTrace();
}
}
//Resource bundle for localized strings. //Resource bundle for localized strings.
public static ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings"); public static ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings", Locale.forLanguageTag(settings.getProperty("language")));
//Discord client object. //Discord client object.
public static IDiscordClient client; public static IDiscordClient client;
@ -150,6 +163,11 @@ public class HandieBot {
musicPlayer.quitAll(); musicPlayer.quitAll();
client.logout(); client.logout();
window.dispose(); window.dispose();
try {
settings.store(new FileWriter(FileUtil.getDataDirectory()+"settings"), "Settings for HandieBot");
} catch (IOException e) {
e.printStackTrace();
}
System.exit(0); System.exit(0);
} }

View File

@ -1,16 +1,18 @@
package handiebot.view; package handiebot.view;
import handiebot.HandieBot; import handiebot.HandieBot;
import handiebot.lavaplayer.playlist.Playlist; import handiebot.view.tableModels.PlaylistTableModel;
import handiebot.view.tableModels.SongsTableModel;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import java.awt.*; import java.awt.*;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import static handiebot.HandieBot.resourceBundle; import static handiebot.HandieBot.resourceBundle;
@ -24,10 +26,8 @@ public class BotWindow extends JFrame {
private JTextPane outputArea; private JTextPane outputArea;
//Playlist display variables. //Playlist display variables.
private DefaultListModel<String> playlistNamesModel; private PlaylistTableModel playlistTableModel;
private DefaultListModel<String> currentPlaylistModel; private SongsTableModel songsTableModel;
private JList<String> playlistNamesList;
private JList<String> currentPlaylistList;
private ListSelectionListener playlistListener; private ListSelectionListener playlistListener;
private JPanel playlistDisplayPanel; private JPanel playlistDisplayPanel;
@ -43,29 +43,30 @@ public class BotWindow extends JFrame {
scrollPane.setAutoscrolls(true); scrollPane.setAutoscrolls(true);
getContentPane().add(scrollPane, BorderLayout.CENTER); getContentPane().add(scrollPane, BorderLayout.CENTER);
//Playlist shower //updatePlaylistNames();
this.playlistNamesModel = new DefaultListModel<>();
this.currentPlaylistModel = new DefaultListModel<>();
this.playlistNamesList = new JList<>(this.playlistNamesModel);
this.playlistNamesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.currentPlaylistList = new JList<>(this.currentPlaylistModel);
this.currentPlaylistList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
updatePlaylistNames();
this.playlistNamesList.addListSelectionListener(new PlaylistSelectionListener(this.currentPlaylistModel));
//Create the panel to hold both of the sub-panels.
playlistDisplayPanel = new JPanel(); playlistDisplayPanel = new JPanel();
playlistDisplayPanel.setPreferredSize(new Dimension(250, 0)); playlistDisplayPanel.setPreferredSize(new Dimension(250, 0));
playlistDisplayPanel.setLayout(new BorderLayout()); playlistDisplayPanel.setLayout(new BorderLayout());
this.songsTableModel = new SongsTableModel();
this.playlistTableModel = new PlaylistTableModel();
JTable songsTable = new JTable(this.songsTableModel);
JTable playlistTable = new JTable(playlistTableModel);
//Playlist name scroll pane. //Playlist name scroll pane.
JScrollPane playlistNamesScrollPane = new JScrollPane(playlistNamesList); playlistTable.setRowSelectionAllowed(true);
playlistNamesScrollPane.setColumnHeaderView(new JLabel("Playlists")); playlistTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
playlistTable.getSelectionModel().addListSelectionListener(new PlaylistSelectionListener(this.songsTableModel, playlistTable, songsTable));
JScrollPane playlistNamesScrollPane = new JScrollPane(playlistTable);
playlistNamesScrollPane.setPreferredSize(new Dimension(250, 200));
playlistDisplayPanel.add(playlistNamesScrollPane, BorderLayout.PAGE_START); playlistDisplayPanel.add(playlistNamesScrollPane, BorderLayout.PAGE_START);
//Song names scroll pane. //Song names scroll pane.
JScrollPane songNamesScrollPane = new JScrollPane(this.currentPlaylistList); songsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
songsTable.setRowSelectionAllowed(true);
songsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane songNamesScrollPane = new JScrollPane(songsTable);
songNamesScrollPane.setColumnHeaderView(new JLabel("Selected Playlist")); songNamesScrollPane.setColumnHeaderView(new JLabel("Selected Playlist"));
playlistDisplayPanel.add(songNamesScrollPane, BorderLayout.CENTER); playlistDisplayPanel.add(songNamesScrollPane, BorderLayout.CENTER);
@ -110,11 +111,7 @@ public class BotWindow extends JFrame {
* Updates the list of playlist names. * Updates the list of playlist names.
*/ */
public void updatePlaylistNames(){ public void updatePlaylistNames(){
List<String> playlistNames = Playlist.getAvailablePlaylists(); this.playlistTableModel = new PlaylistTableModel();
this.playlistNamesModel.clear();
for (String name : playlistNames){
this.playlistNamesModel.addElement(name);
}
} }
/** /**
@ -124,6 +121,25 @@ public class BotWindow extends JFrame {
this.playlistDisplayPanel.setVisible(!this.playlistDisplayPanel.isVisible()); this.playlistDisplayPanel.setVisible(!this.playlistDisplayPanel.isVisible());
} }
/**
* Automatically resizes a table to shrink the index column.
* @param table The table to resize.
*/
public static void autoSizeTable(JTable table){
final TableColumnModel columnModel = table.getColumnModel();
int freeSpace = 230;
for (int col = 0; col < columnModel.getColumnCount(); col++) {
int width = 0;
for (int row = 0; row < table.getRowCount(); row++) {
TableCellRenderer renderer = table.getCellRenderer(row, col);
Component component = table.prepareRenderer(renderer, row, col);
width = Math.max(component.getPreferredSize().width + 1, width);
}
columnModel.getColumn(col).setPreferredWidth(width);
freeSpace -= width;
}
}
public JTextPane getOutputArea(){ public JTextPane getOutputArea(){
return this.outputArea; return this.outputArea;
} }

View File

@ -9,6 +9,7 @@ import java.util.Locale;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import static handiebot.HandieBot.resourceBundle; import static handiebot.HandieBot.resourceBundle;
import static handiebot.HandieBot.settings;
/** /**
* @author Andrew Lalis & Zino Holwerda * @author Andrew Lalis & Zino Holwerda
@ -26,10 +27,18 @@ public class MenuBar extends JMenuBar {
this.add(fileMenu); this.add(fileMenu);
JMenu viewMenu = new JMenu(resourceBundle.getString("menu.viewMenu.view")); JMenu viewMenu = new JMenu(resourceBundle.getString("menu.viewMenu.view"));
JMenu language = new JMenu(resourceBundle.getString("menu.viewMenu.language")); JMenu language = new JMenu(resourceBundle.getString("menu.viewMenu.language"));
language.add(new ActionItem(resourceBundle.getString("menu.viewMenu.language.english"), e -> resourceBundle = ResourceBundle.getBundle("Strings", Locale.US))); language.add(new ActionItem(resourceBundle.getString("menu.viewMenu.language.english"), e -> {
language.add(new ActionItem(resourceBundle.getString("menu.viewMenu.language.dutch"), e -> resourceBundle = ResourceBundle.getBundle("Strings", Locale.forLanguageTag("nl")))); resourceBundle = ResourceBundle.getBundle("Strings", Locale.US);
settings.setProperty("language", "en");
}));
language.add(new ActionItem(resourceBundle.getString("menu.viewMenu.language.dutch"), e -> {
resourceBundle = ResourceBundle.getBundle("Strings", Locale.forLanguageTag("nl"));
settings.setProperty("language", "nl");
}));
viewMenu.add(language); viewMenu.add(language);
viewMenu.add(new ActionItem(resourceBundle.getString("menu.viewMenu.playlistsVisible"), e -> window.togglePlaylistsVisibility())); viewMenu.add(new ActionItem(resourceBundle.getString("menu.viewMenu.playlistsVisible"), e -> window.togglePlaylistsVisibility()));
//TODO: Add method to toggle visibility of the servers panel.
viewMenu.add(new ActionItem(resourceBundle.getString("menu.viewMenu.serversVisible"), e -> {}));
this.add(viewMenu); this.add(viewMenu);
} }

View File

@ -1,12 +1,11 @@
package handiebot.view; package handiebot.view;
import handiebot.lavaplayer.playlist.Playlist; import handiebot.lavaplayer.playlist.Playlist;
import handiebot.lavaplayer.playlist.UnloadedTrack; import handiebot.view.tableModels.SongsTableModel;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import java.util.List;
/** /**
* @author Andrew Lalis * @author Andrew Lalis
@ -14,16 +13,24 @@ import java.util.List;
*/ */
public class PlaylistSelectionListener implements ListSelectionListener { public class PlaylistSelectionListener implements ListSelectionListener {
private DefaultListModel<String> songsListModel; //The table model for the songs list.
private SongsTableModel songsModel;
public PlaylistSelectionListener(DefaultListModel<String> songsListModel){ //The table that shows the playlist names.
this.songsListModel = songsListModel; private JTable table;
private JTable songsTable;
public PlaylistSelectionListener(SongsTableModel songsModel, JTable table, JTable songsTable){
this.songsModel = songsModel;
this.table = table;
this.songsTable = songsTable;
} }
@Override @Override
public void valueChanged(ListSelectionEvent e) { public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()){ if (e.getValueIsAdjusting()){
updatePlaylistData((JList<String>) e.getSource()); updatePlaylistData();
BotWindow.autoSizeTable(songsTable);
} }
} }
@ -31,16 +38,12 @@ public class PlaylistSelectionListener implements ListSelectionListener {
* Updates the list of songs for a selected playlist. * Updates the list of songs for a selected playlist.
* Does not update the list of playlists. * Does not update the list of playlists.
*/ */
private void updatePlaylistData(JList<String> playlistNamesList) { private void updatePlaylistData() {
String selectedValue = playlistNamesList.getSelectedValue(); String selectedValue = (String) this.table.getModel().getValueAt(this.table.getSelectedRow(), 0);
if (selectedValue != null && Playlist.playlistExists(selectedValue)){ if (selectedValue != null && Playlist.playlistExists(selectedValue)){
Playlist playlist = new Playlist(selectedValue); Playlist playlist = new Playlist(selectedValue);
playlist.load(); playlist.load();
List<UnloadedTrack> tracks = playlist.getTracks(); this.songsModel.setPlaylist(playlist);
songsListModel.clear();
for (int i = 0; i < playlist.getTrackCount(); i++){
songsListModel.addElement(tracks.get(i).getTitle());
}
} }
} }

View File

@ -0,0 +1,56 @@
package handiebot.view.tableModels;
import handiebot.lavaplayer.playlist.Playlist;
import javax.swing.table.AbstractTableModel;
import java.util.List;
/**
* @author Andrew Lalis
* Class for a model of data to be supplied to a table.
*/
public class PlaylistTableModel extends AbstractTableModel {
private static final String[] columnNames = {
"Playlist",
"Tracks"
};
private String[][] data;
public PlaylistTableModel(){
List<String> playlistNames = Playlist.getAvailablePlaylists();
data = new String[playlistNames.size()][columnNames.length];
for (int i = 0; i < playlistNames.size(); i++){
data[i][0] = playlistNames.get(i);
Playlist p = new Playlist(playlistNames.get(i));
p.load();
data[i][1] = Integer.toString(p.getTrackCount());
}
}
@Override
public int getRowCount() {
return data.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public String getColumnName(int col) {
return columnNames[col];
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
data[rowIndex][columnIndex] = (String)aValue;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
}

View File

@ -0,0 +1,58 @@
package handiebot.view.tableModels;
import handiebot.lavaplayer.playlist.Playlist;
import javax.swing.table.AbstractTableModel;
/**
* @author Andrew Lalis
*/
public class SongsTableModel extends AbstractTableModel {
private static final String[] columnNames = {
"#",
"Song",
"Time"
};
private String[][] data;
public SongsTableModel(Playlist playlist){
setPlaylist(playlist);
}
public SongsTableModel(){
this.data = new String[0][0];
}
@Override
public int getRowCount() {
return data.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
public void setPlaylist(Playlist playlist){
this.data = new String[playlist.getTrackCount()][columnNames.length];
for (int i = 0; i < playlist.getTrackCount(); i++){
this.data[i][0] = Integer.toString(i+1);
this.data[i][1] = playlist.getTracks().get(i).getTitle();
this.data[i][2] = playlist.getTracks().get(i).getFormattedDuration().replace("[","").replace("]","");
}
this.fireTableDataChanged();
}
}

View File

@ -21,6 +21,7 @@ menu.viewMenu.language=Language
menu.viewMenu.language.english=English menu.viewMenu.language.english=English
menu.viewMenu.language.dutch=Dutch menu.viewMenu.language.dutch=Dutch
menu.viewMenu.playlistsVisible=Playlists menu.viewMenu.playlistsVisible=Playlists
menu.viewMenu.serversVisible=Servers
#Actions #Actions
action.menu.playlist=Edit playlists action.menu.playlist=Edit playlists
action.menu.playlist.add=Add action.menu.playlist.add=Add

View File

@ -0,0 +1,2 @@
#HandieBot default settings
language:en