Heavy modifications have been made to support drag/drop of media to quickly insert disk images, also to start showing indicator icons at the bottom of the screen.

This commit is contained in:
Brendan Robert 2015-03-14 03:23:32 -05:00
parent 50ffe8aab6
commit a9132f8e76
30 changed files with 426 additions and 2252 deletions

View File

@ -1,4 +1,4 @@
/* /**
* Copyright (C) 2012 Brendan Robert (BLuRry) brendan.robert@gmail.com. * Copyright (C) 2012 Brendan Robert (BLuRry) brendan.robert@gmail.com.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -42,10 +42,15 @@ import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import javafx.embed.swing.SwingFXUtils; import javafx.embed.swing.SwingFXUtils;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage; import javafx.stage.Stage;
@ -245,7 +250,7 @@ public class EmulatorUILogic implements Reconfigurable {
description = "Adjusts window size to 1:1 aspect ratio for optimal viewing.", description = "Adjusts window size to 1:1 aspect ratio for optimal viewing.",
alternatives = "Adjust screen;Adjust window size;Adjust aspect ratio;Fix screen;Fix window size;Fix aspect ratio;Correct aspect ratio;", alternatives = "Adjust screen;Adjust window size;Adjust aspect ratio;Fix screen;Fix window size;Fix aspect ratio;Correct aspect ratio;",
defaultKeyMapping = "ctrl+shift+a") defaultKeyMapping = "ctrl+shift+a")
static public void scaleIntegerRatio() { static public void scaleIntegerRatio() {
// AbstractEmulatorFrame frame = Emulator.getFrame(); // AbstractEmulatorFrame frame = Emulator.getFrame();
// if (frame == null) { // if (frame == null) {
@ -358,7 +363,7 @@ public class EmulatorUILogic implements Reconfigurable {
category = "general", category = "general",
description = "Edit emulator configuraion", description = "Edit emulator configuraion",
alternatives = "Reconfigure,Preferences,Settings", alternatives = "Reconfigure,Preferences,Settings",
defaultKeyMapping = {"f4","ctrl+shift+c"}) defaultKeyMapping = {"f4", "ctrl+shift+c"})
public static void showConfig() { public static void showConfig() {
FXMLLoader fxmlLoader = new FXMLLoader(EmulatorUILogic.class.getResource("/fxml/Configuration.fxml")); FXMLLoader fxmlLoader = new FXMLLoader(EmulatorUILogic.class.getResource("/fxml/Configuration.fxml"));
fxmlLoader.setResources(null); fxmlLoader.setResources(null);
@ -372,23 +377,7 @@ public class EmulatorUILogic implements Reconfigurable {
configWindow.show(); configWindow.show();
} catch (IOException exception) { } catch (IOException exception) {
throw new RuntimeException(exception); throw new RuntimeException(exception);
} }
}
public static final String MEDIA_MANAGER_DIALOG_NAME = "Media Manager";
public static final String MEDIA_MANAGER_EDIT_DIALOG_NAME = "Media Details";
@InvokableAction(
name = "Media Manager",
category = "general",
description = "Show the media manager",
alternatives = "Insert disk;Eject disk;Browse;Download;Select",
defaultKeyMapping = {"f1","ctrl+shift+o"})
public static void showMediaManager() {
// if (Emulator.getFrame().getModalDialogUI(MEDIA_MANAGER_DIALOG_NAME) == null) {
// Emulator.getFrame().registerModalDialog(MediaLibrary.getInstance().buildUserInterface(), MEDIA_MANAGER_DIALOG_NAME, null, false);
// }
// Emulator.getFrame().showDialog(MEDIA_MANAGER_DIALOG_NAME);
} }
public static boolean confirm(String message) { public static boolean confirm(String message) {
@ -396,6 +385,43 @@ public class EmulatorUILogic implements Reconfigurable {
return false; return false;
} }
static final Map<Object, Set<Label>> indicators = new HashMap<>();
static public void addIndicator(Object owner, Label icon) {
synchronized (indicators) {
Set<Label> ind = indicators.get(owner);
if (ind == null) {
ind = new HashSet<>();
indicators.put(owner, ind);
}
ind.add(icon);
JaceApplication.singleton.controller.addIndicator(icon);
}
}
static public void removeIndicator(Object owner, Label icon) {
synchronized (indicators) {
Set<Label> ind = indicators.get(owner);
if (ind != null) {
ind.remove(icon);
}
JaceApplication.singleton.controller.removeIndicator(icon);
}
}
static public void removeIndicators(Object owner) {
synchronized (indicators) {
Set<Label> ind = indicators.get(owner);
if (ind == null) {
return;
}
ind.stream().forEach((icon) -> {
JaceApplication.singleton.controller.removeIndicator(icon);
});
indicators.remove(owner);
}
}
@Override @Override
public String getName() { public String getName() {
return "Jace User Interface"; return "Jace User Interface";
@ -409,4 +435,4 @@ public class EmulatorUILogic implements Reconfigurable {
@Override @Override
public void reconfigure() { public void reconfigure() {
} }
} }

View File

@ -6,14 +6,45 @@
package jace; package jace;
import com.sun.glass.ui.Application;
import com.sun.org.apache.xerces.internal.util.URI;
import jace.core.Card;
import jace.core.Computer; import jace.core.Computer;
import jace.library.MediaCache;
import jace.library.MediaConsumer;
import jace.library.MediaConsumerParent;
import jace.library.MediaEntry;
import java.io.File;
import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.input.DragEvent;
import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
/** /**
* *
@ -25,23 +56,32 @@ public class JaceUIController {
@FXML @FXML
private AnchorPane rootPane; private AnchorPane rootPane;
@FXML
private StackPane stackPane;
@FXML @FXML
private Region notificationRegion; private HBox notificationBox;
@FXML @FXML
private ImageView appleScreen; private ImageView appleScreen;
Computer computer;
@FXML @FXML
void initialize() { void initialize() {
assert rootPane != null : "fx:id=\"rootPane\" was not injected: check your FXML file 'JaceUI.fxml'."; assert rootPane != null : "fx:id=\"rootPane\" was not injected: check your FXML file 'JaceUI.fxml'.";
assert notificationRegion != null : "fx:id=\"notificationRegion\" was not injected: check your FXML file 'JaceUI.fxml'."; assert stackPane != null : "fx:id=\"stackPane\" was not injected: check your FXML file 'JaceUI.fxml'.";
assert notificationBox != null : "fx:id=\"notificationBox\" was not injected: check your FXML file 'JaceUI.fxml'.";
assert appleScreen != null : "fx:id=\"appleScreen\" was not injected: check your FXML file 'JaceUI.fxml'."; assert appleScreen != null : "fx:id=\"appleScreen\" was not injected: check your FXML file 'JaceUI.fxml'.";
appleScreen.fitWidthProperty().bind(rootPane.widthProperty()); appleScreen.fitWidthProperty().bind(rootPane.widthProperty());
appleScreen.fitHeightProperty().bind(rootPane.heightProperty()); appleScreen.fitHeightProperty().bind(rootPane.heightProperty());
rootPane.setOnDragEntered(this::processDragEnteredEvent);
rootPane.setOnDragExited(this::processDragExitedEvent);
} }
public void connectComputer(Computer computer) { public void connectComputer(Computer computer) {
this.computer = computer;
appleScreen.setImage(computer.getVideo().getFrameBuffer()); appleScreen.setImage(computer.getVideo().getFrameBuffer());
EventHandler<KeyEvent> keyboardHandler = computer.getKeyboard().getListener(); EventHandler<KeyEvent> keyboardHandler = computer.getKeyboard().getListener();
rootPane.setFocusTraversable(true); rootPane.setFocusTraversable(true);
@ -49,4 +89,136 @@ public class JaceUIController {
rootPane.setOnKeyReleased(keyboardHandler); rootPane.setOnKeyReleased(keyboardHandler);
rootPane.requestFocus(); rootPane.requestFocus();
} }
private void processDragEnteredEvent(DragEvent evt) {
MediaEntry media = null;
if (evt.getDragboard().hasFiles()) {
media = MediaCache.getMediaFromFile(getDraggedFile(evt.getDragboard().getFiles()));
} else if (evt.getDragboard().hasUrl()) {
media = MediaCache.getMediaFromUrl(evt.getDragboard().getUrl());
} else if (evt.getDragboard().hasString()) {
String path = evt.getDragboard().getString();
if (URI.isWellFormedAddress(path)) {
media = MediaCache.getMediaFromUrl(path);
} else {
File f = new File(path);
if (f.exists()) {
media = MediaCache.getMediaFromFile(f);
}
}
}
if (media != null) {
evt.acceptTransferModes(TransferMode.LINK, TransferMode.COPY);
startDragEvent(media);
}
}
private void processDragExitedEvent(DragEvent evt) {
endDragEvent();
}
private File getDraggedFile(List<File> files) {
if (files == null || files.isEmpty()) {
return null;
}
for (File f : files) {
if (f.isFile()) return f;
}
return null;
}
HBox drivePanel;
private void startDragEvent(MediaEntry media) {
List<MediaConsumer> consumers = getMediaConsumers();
drivePanel = new HBox();
consumers.stream()
.filter((consumer) -> (consumer.isAccepted(media, media.files.get(0))))
.forEach((consumer) -> {
Label icon = consumer.getIcon();
icon.setTextFill(Color.WHITE);
icon.setPadding(new Insets(2.0));
drivePanel.getChildren().add(icon);
icon.setOnDragOver(event -> {
event.acceptTransferModes(TransferMode.ANY);
event.consume();
});
icon.setOnDragDropped(event -> {
System.out.println("Dropping media on "+icon.getText());
try {
computer.pause();
consumer.insertMedia(media, media.files.get(0));
computer.resume();
event.setDropCompleted(true);
event.consume();
} catch (IOException ex) {
Logger.getLogger(JaceUIController.class.getName()).log(Level.SEVERE, null, ex);
}
endDragEvent();
});
});
stackPane.getChildren().add(drivePanel);
drivePanel.setLayoutX(10);
drivePanel.setLayoutY(10);
}
private void endDragEvent() {
stackPane.getChildren().remove(drivePanel);
drivePanel.getChildren().stream().forEach((n) -> {
n.setOnDragDropped(null);
});
}
private List<MediaConsumer> getMediaConsumers() {
List<MediaConsumer> consumers = new ArrayList<>();
for (Optional<Card> card : computer.memory.getAllCards()) {
card.filter(c -> c instanceof MediaConsumerParent).ifPresent(parent -> {
consumers.addAll(Arrays.asList(((MediaConsumerParent) parent).getConsumers()));
});
}
return consumers;
}
Map<Label, Long> iconTTL = new ConcurrentHashMap<>();
void addIndicator(Label icon) {
if (!iconTTL.containsKey(icon)) {
Application.invokeLater(()->{
if (!notificationBox.getChildren().contains(icon)) {
notificationBox.getChildren().add(icon);
}
});
}
trackTTL(icon);
}
void removeIndicator(Label icon) {
Application.invokeLater(()->{
notificationBox.getChildren().remove(icon);
iconTTL.remove(icon);
});
}
ScheduledExecutorService notificationExecutor = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture ttlCleanupTask = null;
private void trackTTL(Label icon) {
iconTTL.put(icon, System.currentTimeMillis()+250L);
if (ttlCleanupTask == null || ttlCleanupTask.isCancelled()) {
ttlCleanupTask = notificationExecutor.scheduleWithFixedDelay(this::processTTL, 1, 100, TimeUnit.MILLISECONDS);
}
}
private void processTTL() {
Long now = System.currentTimeMillis();
for (Iterator<Label> iterator = iconTTL.keySet().iterator(); iterator.hasNext();) {
Label icon = iterator.next();
if (iconTTL.get(icon) <= now) {
removeIndicator(icon);
}
}
if (iconTTL.isEmpty()) {
ttlCleanupTask.cancel(true);
ttlCleanupTask = null;
}
}
} }

View File

@ -95,8 +95,7 @@ public class Configuration implements Reconfigurable {
} }
public static ImageView getChangedIcon() { public static ImageView getChangedIcon() {
InputStream imgStream = Configuration.class.getResourceAsStream("/jace/data/icon_exclaim.gif"); return new ImageView(Utility.loadIcon("icon_exclaim.gif"));
return new ImageView(new Image(imgStream));
} }
@Override @Override

View File

@ -6,12 +6,14 @@ import java.io.Serializable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javafx.beans.Observable; import javafx.beans.Observable;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
@ -28,6 +30,7 @@ import javafx.scene.control.TreeView;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.util.StringConverter; import javafx.util.StringConverter;
public class ConfigurationUIController { public class ConfigurationUIController {
@ -173,6 +176,7 @@ public class ConfigurationUIController {
return null; return null;
} }
HBox row = new HBox(); HBox row = new HBox();
row.getStyleClass().add("setting-row");
Label label = new Label(fieldInfo.name()); Label label = new Label(fieldInfo.name());
label.getStyleClass().add("setting-label"); label.getStyleClass().add("setting-label");
label.setMinWidth(150.0); label.setMinWidth(150.0);
@ -189,16 +193,27 @@ public class ConfigurationUIController {
return null; return null;
} }
HBox row = new HBox(); HBox row = new HBox();
row.getStyleClass().add("setting-row");
Label label = new Label(actionInfo.name()); Label label = new Label(actionInfo.name());
label.getStyleClass().add("setting-keyboard-shortcut"); label.getStyleClass().add("setting-keyboard-shortcut");
label.setMinWidth(150.0); label.setMinWidth(150.0);
TextField widget = new TextField(String.valueOf(values)); String value = Arrays.stream(values).collect(Collectors.joining(" or "));
Text widget = new Text(value);
widget.setWrappingWidth(180.0);
widget.getStyleClass().add("setting-keyboard-value");
widget.setOnMouseClicked((event) -> {
editKeyboardShortcut(node, actionName, widget);
});
label.setLabelFor(widget); label.setLabelFor(widget);
row.getChildren().add(label); row.getChildren().add(label);
row.getChildren().add(widget); row.getChildren().add(widget);
return row; return row;
} }
private void editKeyboardShortcut(ConfigNode node, String actionName, Text widget) {
throw new UnsupportedOperationException("Not supported yet.");
}
private Node buildEditField(ConfigNode node, String settingName, Serializable value) { private Node buildEditField(ConfigNode node, String settingName, Serializable value) {
Field field; Field field;
try { try {
@ -220,7 +235,7 @@ public class ConfigurationUIController {
return buildTextField(node, settingName, value, null); return buildTextField(node, settingName, value, null);
} }
} else if (type.equals(File.class)) { } else if (type.equals(File.class)) {
return buildFileSelectionField(node, settingName, value); // TODO: Add file support!
} else if (Class.class.isEnum()) { } else if (Class.class.isEnum()) {
// TODO: Add enumeration support! // TODO: Add enumeration support!
} else if (ISelection.class.isAssignableFrom(type)) { } else if (ISelection.class.isAssignableFrom(type)) {
@ -246,10 +261,6 @@ public class ConfigurationUIController {
return widget; return widget;
} }
private Node buildFileSelectionField(ConfigNode node, String settingName, Serializable value) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
private Node buildDynamicSelectComponent(ConfigNode node, String settingName, Serializable value) { private Node buildDynamicSelectComponent(ConfigNode node, String settingName, Serializable value) {
try { try {
DynamicSelection sel = (DynamicSelection) node.subject.getClass().getField(settingName).get(node.subject); DynamicSelection sel = (DynamicSelection) node.subject.getClass().getField(settingName).get(node.subject);

View File

@ -21,7 +21,6 @@ package jace.core;
import jace.config.ConfigurableField; import jace.config.ConfigurableField;
import jace.config.InvokableAction; import jace.config.InvokableAction;
import jace.config.Reconfigurable; import jace.config.Reconfigurable;
import jace.library.MediaLibrary;
import jace.state.StateManager; import jace.state.StateManager;
import java.io.IOException; import java.io.IOException;
import java.util.Optional; import java.util.Optional;
@ -42,7 +41,6 @@ public abstract class Computer implements Reconfigurable {
public Keyboard keyboard; public Keyboard keyboard;
public StateManager stateManager; public StateManager stateManager;
public Motherboard motherboard; public Motherboard motherboard;
public MediaLibrary mediaLibrary = MediaLibrary.getInstance();
@ConfigurableField(category = "advanced", name = "State management", shortName = "rewind", description = "This enables rewind support, but consumes a lot of memory when active.") @ConfigurableField(category = "advanced", name = "State management", shortName = "rewind", description = "This enables rewind support, but consumes a lot of memory when active.")
public boolean enableStateManager; public boolean enableStateManager;

View File

@ -22,6 +22,7 @@ import java.awt.BorderLayout;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -43,8 +44,14 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javafx.geometry.Pos;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JProgressBar; import javax.swing.JProgressBar;
@ -274,12 +281,36 @@ public class Utility {
return result; return result;
} }
public static ImageIcon loadIcon(String filename) { public static Image loadIcon(String filename) {
URL imageUrl = Utility.class.getClassLoader().getResource("jace/data/" + filename); InputStream stream = Utility.class.getClassLoader().getResourceAsStream("jace/data/" + filename);
ImageIcon i = new ImageIcon(imageUrl); return new Image(stream);
return i;
} }
public static Label loadIconLabel(String filename) {
Image img = loadIcon(filename);
Label label = new Label() {
@Override
public boolean equals(Object obj) {
if (obj instanceof Label) {
Label l2 = (Label) obj;
return super.equals(l2) || l2.getText().equals(getText());
} else {
return super.equals(obj);
}
}
};
label.setGraphic(new ImageView(img));
label.setAlignment(Pos.CENTER);
label.setContentDisplay(ContentDisplay.TOP);
label.setTextFill(Color.WHITE);
DropShadow shadow = new DropShadow(5.0, Color.BLACK);
label.setEffect(shadow);
return label;
}
public static void runModalProcess(String title, final Runnable runnable) { public static void runModalProcess(String title, final Runnable runnable) {
// final JDialog frame = new JDialog(Emulator.getFrame()); // final JDialog frame = new JDialog(Emulator.getFrame());
final JProgressBar progressBar = new JProgressBar(); final JProgressBar progressBar = new JProgressBar();

View File

@ -32,14 +32,11 @@ import jace.state.Stateful;
import jace.core.Utility; import jace.core.Utility;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.MouseInfo; import java.awt.MouseInfo;
import java.awt.Point; import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import javax.swing.ImageIcon; import javafx.scene.control.Label;
/** /**
* Apple Mouse interface implementation. This is fully compatible with several * Apple Mouse interface implementation. This is fully compatible with several
@ -86,7 +83,7 @@ public class CardAppleMouse extends Card implements MouseListener {
public static int CYCLES_PER_UPDATE = (int) (1020484L / 60L); public static int CYCLES_PER_UPDATE = (int) (1020484L / 60L);
@ConfigurableField(name = "Fullscreen fix", shortName = "fsfix", category = "Mouse", description = "If the mouse pointer is a little off when in fullscreen, this should fix it.") @ConfigurableField(name = "Fullscreen fix", shortName = "fsfix", category = "Mouse", description = "If the mouse pointer is a little off when in fullscreen, this should fix it.")
public boolean fullscreenFix = true; public boolean fullscreenFix = true;
ImageIcon mouseActive = Utility.loadIcon("input-mouse.png"); Label mouseActive = Utility.loadIconLabel("input-mouse.png");
public CardAppleMouse(Computer computer) { public CardAppleMouse(Computer computer) {
super(computer); super(computer);
@ -348,7 +345,7 @@ public class CardAppleMouse extends Card implements MouseListener {
* Screen holes are updated * Screen holes are updated
*/ */
private void initMouse() { private void initMouse() {
mouseActive.setDescription("Active"); mouseActive.setText("Active");
// Emulator.getFrame().addIndicator(this, mouseActive, 2000); // Emulator.getFrame().addIndicator(this, mouseActive, 2000);
setClampWindowX(0, 0x3ff); setClampWindowX(0, 0x3ff);
setClampWindowY(0, 0x3ff); setClampWindowY(0, 0x3ff);

View File

@ -18,7 +18,7 @@
*/ */
package jace.hardware; package jace.hardware;
import jace.Emulator; import jace.EmulatorUILogic;
import jace.config.ConfigurableField; import jace.config.ConfigurableField;
import jace.config.Name; import jace.config.Name;
import jace.config.Reconfigurable; import jace.config.Reconfigurable;
@ -66,8 +66,8 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
} catch (IOException ex) { } catch (IOException ex) {
Logger.getLogger(CardDiskII.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(CardDiskII.class.getName()).log(Level.SEVERE, null, ex);
} }
drive1.setIcon(Utility.loadIcon("disk_ii.png")); drive1.setIcon(Utility.loadIconLabel("disk_ii.png"));
drive2.setIcon(Utility.loadIcon("disk_ii.png")); drive2.setIcon(Utility.loadIconLabel("disk_ii.png"));
reset(); reset();
} }
@ -106,13 +106,13 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
case 0x8: case 0x8:
// drive off // drive off
currentDrive.setOn(false); currentDrive.setOn(false);
// Emulator.getFrame().removeIndicator(this, currentDrive == drive1 ? diskDrive1Icon : diskDrive2Icon, false); EmulatorUILogic.removeIndicator(this, currentDrive.getIcon());
break; break;
case 0x9: case 0x9:
// drive on // drive on
currentDrive.setOn(true); currentDrive.setOn(true);
// Emulator.getFrame().addIndicator(this, currentDrive.getIcon()); EmulatorUILogic.addIndicator(this, currentDrive.getIcon());
break; break;
case 0xA: case 0xA:
@ -129,8 +129,8 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
// read/write latch // read/write latch
currentDrive.write(); currentDrive.write();
e.setNewValue(currentDrive.readLatch()); e.setNewValue(currentDrive.readLatch());
EmulatorUILogic.addIndicator(this, currentDrive.getIcon());
break; break;
case 0xF: case 0xF:
// write mode // write mode
currentDrive.setWriteMode(); currentDrive.setWriteMode();
@ -167,7 +167,6 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
@Override @Override
protected void handleFirmwareAccess(int register, TYPE type, int value, RAMEvent e) { protected void handleFirmwareAccess(int register, TYPE type, int value, RAMEvent e) {
// Do nothing: The ROM does everything // Do nothing: The ROM does everything
return;
} }
public void loadRom(String path) throws IOException { public void loadRom(String path) throws IOException {
@ -227,10 +226,11 @@ public class CardDiskII extends Card implements Reconfigurable, MediaConsumerPar
@Override @Override
public void setSlot(int slot) { public void setSlot(int slot) {
super.setSlot(slot); super.setSlot(slot);
drive1.getIcon().setDescription("S" + slot + "D1"); drive1.getIcon().setText("S" + slot + "D1");
drive2.getIcon().setDescription("S" + slot + "D2"); drive2.getIcon().setText("S" + slot + "D2");
} }
@Override
public MediaConsumer[] getConsumers() { public MediaConsumer[] getConsumers() {
return new MediaConsumer[]{drive1, drive2}; return new MediaConsumer[]{drive1, drive2};
} }

View File

@ -18,12 +18,10 @@
*/ */
package jace.hardware; package jace.hardware;
import jace.Emulator;
import jace.config.ConfigurableField; import jace.config.ConfigurableField;
import jace.config.Name; import jace.config.Name;
import jace.core.Card; import jace.core.Card;
import jace.core.Computer; import jace.core.Computer;
import jace.core.Motherboard;
import jace.core.RAMEvent; import jace.core.RAMEvent;
import jace.core.RAMEvent.TYPE; import jace.core.RAMEvent.TYPE;
import jace.state.Stateful; import jace.state.Stateful;
@ -33,7 +31,7 @@ import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.ImageIcon; import javafx.scene.control.Label;
/** /**
* This card strives to be a clone of the Applied Engineering RamFactor card * This card strives to be a clone of the Applied Engineering RamFactor card
@ -64,10 +62,10 @@ public class CardRamFactor extends Card {
public String getDeviceName() { public String getDeviceName() {
return "RamFactor"; return "RamFactor";
} }
ImageIcon indicator; Label indicator;
public CardRamFactor(Computer computer) { public CardRamFactor(Computer computer) {
super(computer); super(computer);
indicator=Utility.loadIcon("ram.png"); indicator=Utility.loadIconLabel("ram.png");
try { try {
loadRom("jace/data/RAMFactor14.rom"); loadRom("jace/data/RAMFactor14.rom");
} catch (IOException ex) { } catch (IOException ex) {
@ -206,7 +204,7 @@ public class CardRamFactor extends Card {
@Override @Override
public void setSlot(int slot) { public void setSlot(int slot) {
super.setSlot(slot); super.setSlot(slot);
indicator.setDescription("Slot "+getSlot()); indicator.setText("Slot "+getSlot());
// Rom has different images for each slot // Rom has different images for each slot
updateFirmwareMemory(); updateFirmwareMemory();
} }

View File

@ -33,13 +33,14 @@ import java.net.Socket;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javafx.scene.control.Label;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
/** /**
* Super Serial Card with serial-over-tcp/ip support. This is fully compatible * Super Serial Card with serial-over-tcp/ip support. This is fully compatible
* with the SSC ROM and supported applications. * with the SSC ROM and supported applications.
* *
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com * @author Brendan Robert (BLuRry) brendan.robert@gmail.com
*/ */
@Name("Super Serial Card") @Name("Super Serial Card")
public class CardSSC extends Card implements Reconfigurable, Runnable { public class CardSSC extends Card implements Reconfigurable, Runnable {
@ -97,10 +98,12 @@ public class CardSSC extends Card implements Reconfigurable, Runnable {
super(computer); super(computer);
} }
@Override
public String getDeviceName() { public String getDeviceName() {
return "Super Serial Card"; return "Super Serial Card";
} }
ImageIcon activityIndicator;
Label activityIndicator;
@Override @Override
public void setSlot(int slot) { public void setSlot(int slot) {
@ -110,8 +113,8 @@ public class CardSSC extends Card implements Reconfigurable, Runnable {
Logger.getLogger(CardSSC.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(CardSSC.class.getName()).log(Level.SEVERE, null, ex);
} }
super.setSlot(slot); super.setSlot(slot);
activityIndicator = Utility.loadIcon("network-wired.png"); activityIndicator = Utility.loadIconLabel("network-wired.png");
activityIndicator.setDescription("Slot " + slot); activityIndicator.setText("Slot " + slot);
} }
@Override @Override
@ -176,12 +179,9 @@ public class CardSSC extends Card implements Reconfigurable, Runnable {
@Override @Override
public void reset() { public void reset() {
java.awt.EventQueue.invokeLater(new Runnable() { java.awt.EventQueue.invokeLater(() -> {
@Override suspend();
public void run() { resume();
suspend();
resume();
}
}); });
} }
@ -414,7 +414,8 @@ public class CardSSC extends Card implements Reconfigurable, Runnable {
/** /**
* Detach from server socket port and ensure that the card's resources are * Detach from server socket port and ensure that the card's resources are
* no longer in use * no longer in use
* @return *
* @return
*/ */
@Override @Override
public boolean suspend() { public boolean suspend() {

View File

@ -34,6 +34,7 @@ import java.util.Calendar;
import java.util.Stack; import java.util.Stack;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javafx.scene.control.Label;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
/** /**
@ -49,8 +50,8 @@ import javax.swing.ImageIcon;
@Name("ThunderClock Plus") @Name("ThunderClock Plus")
public class CardThunderclock extends Card { public class CardThunderclock extends Card {
ImageIcon clockIcon; Label clockIcon;
ImageIcon clockFixIcon; Label clockFixIcon;
long lastShownIcon = -1; long lastShownIcon = -1;
// Only mention that the clock is read if it hasn't been checked for over 30 seconds // Only mention that the clock is read if it hasn't been checked for over 30 seconds
// This is to avoid showing it all the time in programs that poll it constantly // This is to avoid showing it all the time in programs that poll it constantly
@ -65,9 +66,9 @@ public class CardThunderclock extends Card {
} catch (IOException ex) { } catch (IOException ex) {
Logger.getLogger(CardDiskII.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(CardDiskII.class.getName()).log(Level.SEVERE, null, ex);
} }
clockIcon = Utility.loadIcon("clock.png"); clockIcon = Utility.loadIconLabel("clock.png");
clockFixIcon = Utility.loadIcon("clock_fix.png"); clockFixIcon = Utility.loadIconLabel("clock_fix.png");
clockFixIcon.setDescription("Fixed"); clockFixIcon.setText("Fixed");
} }
// Raw format: 40 bits, in BCD form (it actually streams out in the reverse order of this, bit 0 first) // Raw format: 40 bits, in BCD form (it actually streams out in the reverse order of this, bit 0 first)
@ -153,7 +154,7 @@ public class CardThunderclock extends Card {
performProdosPatch(); performProdosPatch();
} }
getTime(); getTime();
clockIcon.setDescription("Slot " + getSlot()); clockIcon.setText("Slot " + getSlot());
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if ((now - lastShownIcon) > MIN_WAIT) { if ((now - lastShownIcon) > MIN_WAIT) {
// Emulator.getFrame().addIndicator(this, clockIcon, 3000); // Emulator.getFrame().addIndicator(this, clockIcon, 3000);

View File

@ -29,7 +29,7 @@ import java.io.IOException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.LockSupport;
import javax.swing.ImageIcon; import javafx.scene.control.Label;
/** /**
* This implements the mechanical part of the disk drive and tracks changes to * This implements the mechanical part of the disk drive and tracks changes to
@ -222,19 +222,20 @@ public class DiskIIDrive implements MediaConsumer {
void insertDisk(File diskPath) throws IOException { void insertDisk(File diskPath) throws IOException {
disk = new FloppyDisk(diskPath, computer); disk = new FloppyDisk(diskPath, computer);
System.out.println("Inserting "+diskPath.getPath()+" into "+getIcon().getText());
dirtyTracks = new HashSet<>(); dirtyTracks = new HashSet<>();
// Emulator state has changed significantly, reset state manager // Emulator state has changed significantly, reset state manager
StateManager.getInstance(computer).invalidate(); StateManager.getInstance(computer).invalidate();
} }
private ImageIcon icon; private Label icon;
@Override @Override
public ImageIcon getIcon() { public Label getIcon() {
return icon; return icon;
} }
@Override @Override
public void setIcon(ImageIcon i) { public void setIcon(Label i) {
icon = i; icon = i;
} }
private MediaEntry currentMediaEntry; private MediaEntry currentMediaEntry;
@ -276,7 +277,7 @@ public class DiskIIDrive implements MediaConsumer {
@Override @Override
public boolean isAccepted(MediaEntry e, MediaFile f) { public boolean isAccepted(MediaEntry e, MediaFile f) {
if (f == null) return false; if (f == null) return false;
System.out.println("Type is accepted: "+f.path+"; "+e.type.toString()+": "+e.type.is140kb); // System.out.println("Type is accepted: "+f.path+"; "+e.type.toString()+": "+e.type.is140kb);
return e.type.is140kb; return e.type.is140kb;
} }

View File

@ -18,7 +18,6 @@
*/ */
package jace.hardware.massStorage; package jace.hardware.massStorage;
import jace.Emulator;
import jace.apple2e.MOS65C02; import jace.apple2e.MOS65C02;
import jace.config.Name; import jace.config.Name;
import jace.core.Card; import jace.core.Card;
@ -51,16 +50,17 @@ public class CardMassStorage extends Card implements MediaConsumerParent {
super(computer); super(computer);
drive1 = new MassStorageDrive(); drive1 = new MassStorageDrive();
drive2 = new MassStorageDrive(); drive2 = new MassStorageDrive();
drive1.setIcon(Utility.loadIcon("drive-harddisk.png")); drive1.setIcon(Utility.loadIconLabel("drive-harddisk.png"));
drive2.setIcon(Utility.loadIcon("drive-harddisk.png")); drive2.setIcon(Utility.loadIconLabel("drive-harddisk.png"));
drive1.onInsert(this::reconfigure);
currentDrive = drive1; currentDrive = drive1;
} }
@Override @Override
public void setSlot(int slot) { public void setSlot(int slot) {
super.setSlot(slot); super.setSlot(slot);
drive1.getIcon().setDescription("S" + getSlot() + "D1"); drive1.getIcon().setText("S" + getSlot() + "D1");
drive2.getIcon().setDescription("S" + getSlot() + "D2"); drive2.getIcon().setText("S" + getSlot() + "D2");
} }
@Override @Override

View File

@ -84,7 +84,7 @@ public class LargeDisk implements IDisk {
@Override @Override
public void boot0(int slot, Computer computer) throws IOException { public void boot0(int slot, Computer computer) throws IOException {
computer.getCpu().suspend(); computer.pause();
mliRead(0, 0x0800, computer.getMemory()); mliRead(0, 0x0800, computer.getMemory());
byte slot16 = (byte) (slot << 4); byte slot16 = (byte) (slot << 4);
((MOS65C02) computer.getCpu()).X = slot16; ((MOS65C02) computer.getCpu()).X = slot16;
@ -95,7 +95,7 @@ public class LargeDisk implements IDisk {
// Write location to block read routine to zero page // Write location to block read routine to zero page
memory.writeWord(0x048, 0x0c000 + CardMassStorage.DEVICE_DRIVER_OFFSET + (slot * 0x0100), false, false); memory.writeWord(0x048, 0x0c000 + CardMassStorage.DEVICE_DRIVER_OFFSET + (slot * 0x0100), false, false);
((MOS65C02) computer.getCpu()).setProgramCounter(0x0800); ((MOS65C02) computer.getCpu()).setProgramCounter(0x0800);
computer.getCpu().resume(); computer.resume();
} }
public File getPhysicalPath() { public File getPhysicalPath() {

View File

@ -25,7 +25,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.ImageIcon; import javafx.scene.control.Label;
/** /**
* *
@ -33,13 +33,13 @@ import javax.swing.ImageIcon;
*/ */
public class MassStorageDrive implements MediaConsumer { public class MassStorageDrive implements MediaConsumer {
IDisk disk = null; IDisk disk = null;
ImageIcon icon = null; Label icon = null;
public ImageIcon getIcon() { public Label getIcon() {
return icon; return icon;
} }
public void setIcon(ImageIcon i) { public void setIcon(Label i) {
icon = i; icon = i;
} }
@ -51,8 +51,16 @@ public class MassStorageDrive implements MediaConsumer {
currentEntry = e; currentEntry = e;
currentFile = f; currentFile = f;
disk= readDisk(currentFile.path); disk= readDisk(currentFile.path);
if (postInsertAction != null) {
postInsertAction.run();
}
} }
Runnable postInsertAction = null;
public void onInsert(Runnable r) {
postInsertAction = r;
}
public MediaEntry getMediaEntry() { public MediaEntry getMediaEntry() {
return currentEntry; return currentEntry;
} }
@ -65,6 +73,7 @@ public class MassStorageDrive implements MediaConsumer {
return e.type.isProdosOrdered; return e.type.isProdosOrdered;
} }
public void eject() { public void eject() {
if (disk != null) { if (disk != null) {
disk.eject(); disk.eject();

View File

@ -1,59 +0,0 @@
/*
* Copyright (C) 2013 brobert.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package jace.library;
import java.awt.Image;
import java.awt.datatransfer.Transferable;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.TransferHandler;
/**
*
* @author brobert
*/
class DiskTransferHandler extends TransferHandler {
public DiskTransferHandler() {
}
@Override
public int getSourceActions(JComponent c) {
return COPY;
}
MediaEntry currentEntry = null;
@Override
protected Transferable createTransferable(JComponent c) {
JList list = (JList) c;
MediaEntry entry = (MediaEntry) list.getSelectedValue();
System.out.println("Transferrable --> " + entry.name);
currentEntry = entry;
return new TransferableMediaEntry(entry);
}
@Override
public Image getDragImage() {
if (currentEntry == null) {
return super.getDragImage();
} else {
return currentEntry.type.diskIcon;
}
}
}

View File

@ -20,10 +20,8 @@ package jace.library;
import jace.core.Utility; import jace.core.Utility;
import jace.hardware.FloppyDisk; import jace.hardware.FloppyDisk;
import java.awt.Image;
import java.io.File; import java.io.File;
import javax.swing.Icon; import javafx.scene.image.Image;
import javax.swing.ImageIcon;
/** /**
* *
@ -47,7 +45,7 @@ public enum DiskType {
description = desc; description = desc;
is140kb = is140; is140kb = is140;
isProdosOrdered = po; isProdosOrdered = po;
diskIcon = Utility.loadIcon(iconPath).getImage(); diskIcon = Utility.loadIcon(iconPath);
} }
static public DiskType determineType(File file) { static public DiskType determineType(File file) {

View File

@ -1,61 +0,0 @@
/*
* Copyright (C) 2013 brobert.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package jace.library;
import jace.library.MediaEntry.MediaFile;
import jace.ui.OutlinedLabel;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
/**
*
* @author brobert
*/
public class DriveIcon extends OutlinedLabel {
final MediaConsumer target;
public DriveIcon(MediaConsumer mediaTarget) {
super(mediaTarget.getIcon());
target = mediaTarget;
setText(target.getIcon().getDescription());
setDropTarget(new DropTarget() {
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
try {
String data = dtde.getTransferable().getTransferData(DataFlavor.stringFlavor).toString();
long id = Long.parseLong(data);
MediaEntry e = MediaCache.getLocalLibrary().mediaLookup.get(id);
// Once other libraries are implemented, make sure to alias locally!
// MediaEntry entry = MediaCache.getLocalLibrary().findLocalEntry(e);
System.out.println("Inserting "+e.name+" into "+target.toString());
MediaFile f = MediaCache.getLocalLibrary().getCurrentFile(e, true);
target.isAccepted(e, f);
target.insertMedia(e, f);
} catch (Exception ex) {
ex.printStackTrace(System.err);
dtde.rejectDrop();
}
}
});
}
}

View File

@ -37,7 +37,6 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -54,6 +53,23 @@ public class MediaCache implements Serializable {
public static int DELAY_BEFORE_PERSISTING_LIBRARY = 2000; public static int DELAY_BEFORE_PERSISTING_LIBRARY = 2000;
public static MediaCache LOCAL_LIBRARY; public static MediaCache LOCAL_LIBRARY;
public static MediaEntry getMediaFromFile(File draggedFile) {
MediaEntry entry = new MediaEntry();
MediaFile file = new MediaFile();
file.path = draggedFile;
file.temporary = false;
file.activeVersion = true;
entry.files = new ArrayList<>();
entry.files.add(file);
entry.isLocal = true;
entry.type = DiskType.determineType(draggedFile);
return entry;
}
public static MediaEntry getMediaFromUrl(String url) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public Set<Long> favorites; public Set<Long> favorites;
public Map<String, Set<Long>> nameLookup; public Map<String, Set<Long>> nameLookup;
public Map<String, Set<Long>> categoryLookup; public Map<String, Set<Long>> categoryLookup;
@ -62,11 +78,11 @@ public class MediaCache implements Serializable {
public long lastDirtyMarker; public long lastDirtyMarker;
public MediaCache() { public MediaCache() {
favorites = new HashSet<Long>(); favorites = new HashSet<>();
nameLookup = new HashMap<String, Set<Long>>(); nameLookup = new HashMap<>();
categoryLookup = new HashMap<String, Set<Long>>(); categoryLookup = new HashMap<>();
keywordLookup = new HashMap<String, Set<Long>>(); keywordLookup = new HashMap<>();
mediaLookup = new HashMap<Long, MediaEntry>(); mediaLookup = new HashMap<>();
} }
public static MediaCache getLocalLibrary() { public static MediaCache getLocalLibrary() {
@ -85,8 +101,8 @@ public class MediaCache implements Serializable {
} }
private void cleanup(Map<String, Set<Long>> lookup) { private void cleanup(Map<String, Set<Long>> lookup) {
Set<String> remove = new HashSet<String>(); Set<String> remove = new HashSet<>();
for (Entry<String, Set<Long>> entry : lookup.entrySet()) { lookup.entrySet().stream().forEach((entry) -> {
if (entry.getValue() == null || entry.getValue().isEmpty()) { if (entry.getValue() == null || entry.getValue().isEmpty()) {
remove.add(entry.getKey()); remove.add(entry.getKey());
} else { } else {
@ -102,7 +118,7 @@ public class MediaCache implements Serializable {
remove.add(entry.getKey()); remove.add(entry.getKey());
} }
} }
} });
lookup.keySet().removeAll(remove); lookup.keySet().removeAll(remove);
} }
@ -144,7 +160,7 @@ public class MediaCache implements Serializable {
private void cacheEntry(Map<String, Set<Long>> cache, String key, long id) { private void cacheEntry(Map<String, Set<Long>> cache, String key, long id) {
Set<Long> ids = cache.get(key); Set<Long> ids = cache.get(key);
if (ids == null) { if (ids == null) {
ids = new HashSet<Long>(); ids = new HashSet<>();
cache.put(key, ids); cache.put(key, ids);
} }
ids.add(id); ids.add(id);
@ -167,9 +183,9 @@ public class MediaCache implements Serializable {
if (e.files == null) { if (e.files == null) {
return; return;
} }
for (MediaEntry.MediaFile f : e.files) { e.files.stream().forEach((f) -> {
f.path.delete(); f.path.delete();
} });
Utility.gripe("All disk images for " + e.name + " have been deleted."); Utility.gripe("All disk images for " + e.name + " have been deleted.");
} }
@ -178,7 +194,7 @@ public class MediaCache implements Serializable {
return null; return null;
} }
if (e.files == null || e.files.isEmpty()) { if (e.files == null || e.files.isEmpty()) {
e.files = new ArrayList<MediaFile>(); e.files = new ArrayList<>();
getLocalLibrary().add(e); getLocalLibrary().add(e);
getLocalLibrary().createBlankFile(e, "Initial", !isPermanent); getLocalLibrary().createBlankFile(e, "Initial", !isPermanent);
getLocalLibrary().downloadImage(e, e.files.get(0), true); getLocalLibrary().downloadImage(e, e.files.get(0), true);
@ -193,14 +209,14 @@ public class MediaCache implements Serializable {
} }
public void saveFile(MediaEntry e, InputStream data) { public void saveFile(MediaEntry e, InputStream data) {
saveFile(getCurrentFile(e, MediaLibrary.CREATE_LOCAL_ON_SAVE), data); // saveFile(getCurrentFile(e, MediaLibrary.CREATE_LOCAL_ON_SAVE), data);
} }
public void saveFile(MediaFile f, InputStream data) { public void saveFile(MediaFile f, InputStream data) {
// TODO: If file is temporary but is supposed to be created local when saved, then move the save to a permanent file!! // TODO: If file is temporary but is supposed to be created local when saved, then move the save to a permanent file!!
if (f.temporary && MediaLibrary.CREATE_LOCAL_ON_SAVE) { // if (f.temporary && MediaLibrary.CREATE_LOCAL_ON_SAVE) {
f = convertTemporaryFileToLocal(f); // f = convertTemporaryFileToLocal(f);
} // }
FileOutputStream fos = null; FileOutputStream fos = null;
f.lastWritten = System.currentTimeMillis(); f.lastWritten = System.currentTimeMillis();
try { try {
@ -219,7 +235,9 @@ public class MediaCache implements Serializable {
Utility.gripe("Could not write disk for " + f.path + " -- I/O Exception: " + ex.getMessage()); Utility.gripe("Could not write disk for " + f.path + " -- I/O Exception: " + ex.getMessage());
} finally { } finally {
try { try {
fos.close(); if (fos != null) {
fos.close();
}
} catch (IOException ex) { } catch (IOException ex) {
Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex);
} }
@ -241,13 +259,7 @@ public class MediaCache implements Serializable {
MediaEntry e = (MediaEntry) in.readObject(); MediaEntry e = (MediaEntry) in.readObject();
add(e); add(e);
} }
} catch (FileNotFoundException ex) { } catch (IOException | ClassNotFoundException ex) {
Utility.gripe(ex.getMessage());
Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Utility.gripe(ex.getMessage());
Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Utility.gripe(ex.getMessage()); Utility.gripe(ex.getMessage());
Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex);
} finally { } finally {
@ -297,6 +309,7 @@ public class MediaCache implements Serializable {
writerWorker = new Thread(new Runnable() { writerWorker = new Thread(new Runnable() {
long timeCheck = 0; long timeCheck = 0;
@Override
public void run() { public void run() {
while (true) { while (true) {
try { try {
@ -334,38 +347,38 @@ public class MediaCache implements Serializable {
public void downloadImage(final MediaEntry e, final MediaFile target, boolean wait) { public void downloadImage(final MediaEntry e, final MediaFile target, boolean wait) {
isDownloading = true; isDownloading = true;
Utility.runModalProcess("Loading disk image...", new Runnable() { Utility.runModalProcess("Loading disk image...", () -> {
public void run() { InputStream in = null;
InputStream in = null; try {
URI uri = null;
try { try {
URI uri = null; uri = new URI(e.source);
try { } catch (URISyntaxException ex) {
uri = new URI(e.source); File f = new File(e.source);
} catch (URISyntaxException ex) { if (f.exists()) {
File f = new File(e.source); uri = f.toURI();
if (f.exists()) {
uri = f.toURI();
}
} }
if (uri == null) { }
Utility.gripe("Unable to resolve path: " + e.source); if (uri == null) {
return;
}
in = uri.toURL().openStream();
saveFile(target, in);
} catch (MalformedURLException ex) {
Utility.gripe("Unable to resolve path: " + e.source); Utility.gripe("Unable to resolve path: " + e.source);
Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex); return;
} catch (IOException ex) { }
Utility.gripe("Unable to download file: " + ex.getMessage()); in = uri.toURL().openStream();
Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex); saveFile(target, in);
} finally { } catch (MalformedURLException ex) {
isDownloading = false; Utility.gripe("Unable to resolve path: " + e.source);
try { Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Utility.gripe("Unable to download file: " + ex.getMessage());
Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex);
} finally {
isDownloading = false;
try {
if (in != null) {
in.close(); in.close();
} catch (IOException ex) {
Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex);
} }
} catch (IOException ex) {
Logger.getLogger(MediaCache.class.getName()).log(Level.SEVERE, null, ex);
} }
} }
}); });
@ -418,14 +431,15 @@ public class MediaCache implements Serializable {
} }
} }
// If there is no current file, download it // If there is no current file, download it
if (MediaLibrary.CREATE_LOCAL_ON_LOAD) { // if (MediaLibrary.CREATE_LOCAL_ON_LOAD) {
getLocalLibrary().add(e); // getLocalLibrary().add(e);
MediaFile f = getCurrentFile(e, true); // MediaFile f = getCurrentFile(e, true);
downloadImage(e, f, true); // downloadImage(e, f, true);
return f; // return f;
} else { // } else {
return downloadTempCopy(e); return downloadTempCopy(e);
} // }
} }
public MediaEntry findLocalEntry(MediaEntry e) { public MediaEntry findLocalEntry(MediaEntry e) {

View File

@ -20,15 +20,15 @@ package jace.library;
import jace.library.MediaEntry.MediaFile; import jace.library.MediaEntry.MediaFile;
import java.io.IOException; import java.io.IOException;
import javax.swing.ImageIcon; import javafx.scene.control.Label;
/** /**
* *
* @author brobert * @author brobert
*/ */
public interface MediaConsumer { public interface MediaConsumer {
public ImageIcon getIcon(); public Label getIcon();
public void setIcon(ImageIcon i); public void setIcon(Label i);
public void insertMedia(MediaEntry e, MediaFile f) throws IOException; public void insertMedia(MediaEntry e, MediaFile f) throws IOException;
public MediaEntry getMediaEntry(); public MediaEntry getMediaEntry();
public MediaFile getMediaFile(); public MediaFile getMediaFile();

View File

@ -1,384 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[600, 400]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="NameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="KeywordsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="SourceLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="DescriptionLabel" min="-2" max="-2" attributes="0"/>
<Component id="AuthorLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="5" max="-2" attributes="0"/>
<Component id="CategoryLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="PublishedLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="SourceField" max="32767" attributes="0"/>
<Component id="NameField" alignment="0" max="32767" attributes="0"/>
<Component id="DescriptionPane" pref="319" max="32767" attributes="0"/>
<Component id="CategoryField" alignment="1" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="YearField" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="PublisherLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="PublisherField" max="32767" attributes="0"/>
</Group>
<Component id="KeywordsField" max="32767" attributes="0"/>
<Component id="AuthorField" alignment="0" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="ReplaceButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="CopyDiskButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="112" max="-2" attributes="0"/>
<Component id="writeProtect" min="-2" pref="140" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="FavoriteField" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="56" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="SaveButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="CancellationButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="ScreenshotCombo" alignment="1" max="32767" attributes="0"/>
<Component id="Screenshot" alignment="1" max="32767" attributes="0"/>
<Component id="InfoLabel" alignment="1" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="Screenshot" min="-2" pref="96" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="ScreenshotCombo" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="InfoLabel" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="CancellationButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="SaveButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="ReplaceButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="CopyDiskButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="NameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="NameField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="SourceField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="SourceLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="DescriptionLabel" min="-2" max="-2" attributes="0"/>
<Component id="DescriptionPane" pref="125" max="32767" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="CategoryLabel" alignment="3" max="32767" attributes="0"/>
<Component id="CategoryField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="YearField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="PublishedLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="PublisherLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="PublisherField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="AuthorField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="AuthorLabel" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="KeywordsField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="KeywordsLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="writeProtect" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="FavoriteField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="NameLabel">
<Properties>
<Property name="text" type="java.lang.String" value="Name"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="Screenshot">
<Properties>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="Screenshot"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[140, 96]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[140, 96]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[140, 192]"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="SourceLabel">
<Properties>
<Property name="text" type="java.lang.String" value="Source (URL)"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="DescriptionLabel">
<Properties>
<Property name="text" type="java.lang.String" value="Description"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="KeywordsLabel">
<Properties>
<Property name="text" type="java.lang.String" value="Keywords"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="CategoryLabel">
<Properties>
<Property name="text" type="java.lang.String" value="Category"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="PublishedLabel">
<Properties>
<Property name="text" type="java.lang.String" value="Published"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="AuthorLabel">
<Properties>
<Property name="text" type="java.lang.String" value="Author"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="SourceField">
<Properties>
<Property name="text" type="java.lang.String" value="http://website/diskImage.dsk"/>
<Property name="toolTipText" type="java.lang.String" value="URL of where disk came from, can also be a local file path"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="NameField">
<Properties>
<Property name="text" type="java.lang.String" value="Disk name"/>
<Property name="toolTipText" type="java.lang.String" value="Name of disk -- if part of a series include side or disk number"/>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="CategoryField">
<Properties>
<Property name="text" type="java.lang.String" value="Category &gt; sub cat &gt; sub cat"/>
<Property name="toolTipText" type="java.lang.String" value="Category (use &gt; marks to separate sub-category)"/>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="DescriptionPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="DescriptionField">
<Properties>
<Property name="columns" type="int" value="20"/>
<Property name="rows" type="int" value="5"/>
<Property name="text" type="java.lang.String" value="Description of disk goes here"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JTextField" name="AuthorField">
<Properties>
<Property name="text" type="java.lang.String" value="Smith, John"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="YearField">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="40">
<StringItem index="0" value="1976"/>
<StringItem index="1" value="1977"/>
<StringItem index="2" value="1978"/>
<StringItem index="3" value="1979"/>
<StringItem index="4" value="1980"/>
<StringItem index="5" value="1981"/>
<StringItem index="6" value="1982"/>
<StringItem index="7" value="1983"/>
<StringItem index="8" value="1984"/>
<StringItem index="9" value="1985"/>
<StringItem index="10" value="1986"/>
<StringItem index="11" value="1987"/>
<StringItem index="12" value="1988"/>
<StringItem index="13" value="1989"/>
<StringItem index="14" value="1990"/>
<StringItem index="15" value="1991"/>
<StringItem index="16" value="1992"/>
<StringItem index="17" value="1993"/>
<StringItem index="18" value="1994"/>
<StringItem index="19" value="1995"/>
<StringItem index="20" value="1996"/>
<StringItem index="21" value="1997"/>
<StringItem index="22" value="1998"/>
<StringItem index="23" value="1999"/>
<StringItem index="24" value="2000"/>
<StringItem index="25" value="2001"/>
<StringItem index="26" value="2002"/>
<StringItem index="27" value="2003"/>
<StringItem index="28" value="2004"/>
<StringItem index="29" value="2005"/>
<StringItem index="30" value="2006"/>
<StringItem index="31" value="2007"/>
<StringItem index="32" value="2008"/>
<StringItem index="33" value="2009"/>
<StringItem index="34" value="2010"/>
<StringItem index="35" value="2011"/>
<StringItem index="36" value="2012"/>
<StringItem index="37" value="2013"/>
<StringItem index="38" value="2014"/>
<StringItem index="39" value="2015"/>
</StringArray>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="KeywordsField">
<Properties>
<Property name="text" type="java.lang.String" value="Keyword1, Keyword2, Keyword3"/>
<Property name="toolTipText" type="java.lang.String" value="Relevant keywords (use commas to separate multiple keywords)"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="FavoriteField">
<Properties>
<Property name="text" type="java.lang.String" value="Show in favorites"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="SaveButton">
<Properties>
<Property name="text" type="java.lang.String" value="Save"/>
<Property name="toolTipText" type="java.lang.String" value="Save metadata changes"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="SaveButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="CancellationButton">
<Properties>
<Property name="text" type="java.lang.String" value="Close"/>
<Property name="toolTipText" type="java.lang.String" value="Abandon metadata changes and close"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="CancellationButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="ReplaceButton">
<Properties>
<Property name="text" type="java.lang.String" value="Replace Disk"/>
<Property name="toolTipText" type="java.lang.String" value="Abandon current disk image and download a new copy from the source URL"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="ReplaceButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="InfoLabel">
<Properties>
<Property name="text" type="java.lang.String" value="Disk usage here"/>
<Property name="verticalAlignment" type="int" value="1"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="CopyDiskButton">
<Properties>
<Property name="text" type="java.lang.String" value="Save copy of disk"/>
<Property name="toolTipText" type="java.lang.String" value="Create a local copy of the disk image on your hard drive"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="CopyDiskButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JComboBox" name="ScreenshotCombo">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="3">
<StringItem index="0" value="Screenshot"/>
<StringItem index="1" value="Box (front)"/>
<StringItem index="2" value="Box (back)"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="ScreenshotComboActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="PublisherField">
<Properties>
<Property name="text" type="java.lang.String" value="Publisher"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="PublisherLabel">
<Properties>
<Property name="text" type="java.lang.String" value="By"/>
</Properties>
</Component>
<Component class="javax.swing.JCheckBox" name="writeProtect">
<Properties>
<Property name="text" type="java.lang.String" value="Write Protect"/>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -1,442 +0,0 @@
/*
* Copyright (C) 2013 brobert.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package jace.library;
import jace.Emulator;
import jace.EmulatorUILogic;
import static jace.EmulatorUILogic.MEDIA_MANAGER_EDIT_DIALOG_NAME;
import jace.library.MediaEntry.MediaFile;
/**
*
* @author brobert
*/
public class MediaEditUI extends javax.swing.JPanel {
public static String CREATE_TITLE = "Create media entry";
public static String EDIT_TITLE = "Edit media entry";
public static String KEYWORD_DELIMITER = ",";
public static String BOX_BACK = "Box (back)";
public static String BOX_FRONT = "Box (front)";
public static String SCREENSHOT = "Screenshot";
/**
* Creates new form MediaEditUI
*/
public MediaEditUI() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
NameLabel = new javax.swing.JLabel();
Screenshot = new javax.swing.JLabel();
SourceLabel = new javax.swing.JLabel();
DescriptionLabel = new javax.swing.JLabel();
KeywordsLabel = new javax.swing.JLabel();
CategoryLabel = new javax.swing.JLabel();
PublishedLabel = new javax.swing.JLabel();
AuthorLabel = new javax.swing.JLabel();
SourceField = new javax.swing.JTextField();
NameField = new javax.swing.JTextField();
CategoryField = new javax.swing.JTextField();
DescriptionPane = new javax.swing.JScrollPane();
DescriptionField = new javax.swing.JTextArea();
AuthorField = new javax.swing.JTextField();
YearField = new javax.swing.JComboBox();
KeywordsField = new javax.swing.JTextField();
FavoriteField = new javax.swing.JCheckBox();
SaveButton = new javax.swing.JButton();
CancellationButton = new javax.swing.JButton();
ReplaceButton = new javax.swing.JButton();
InfoLabel = new javax.swing.JLabel();
CopyDiskButton = new javax.swing.JButton();
ScreenshotCombo = new javax.swing.JComboBox();
PublisherField = new javax.swing.JTextField();
PublisherLabel = new javax.swing.JLabel();
writeProtect = new javax.swing.JCheckBox();
setPreferredSize(new java.awt.Dimension(600, 400));
NameLabel.setText("Name");
Screenshot.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
Screenshot.setText("Screenshot");
Screenshot.setBorder(javax.swing.BorderFactory.createEtchedBorder());
Screenshot.setMaximumSize(new java.awt.Dimension(140, 96));
Screenshot.setMinimumSize(new java.awt.Dimension(140, 96));
Screenshot.setPreferredSize(new java.awt.Dimension(140, 192));
SourceLabel.setText("Source (URL)");
DescriptionLabel.setText("Description");
KeywordsLabel.setText("Keywords");
CategoryLabel.setText("Category");
PublishedLabel.setText("Published");
AuthorLabel.setText("Author");
SourceField.setText("http://website/diskImage.dsk");
SourceField.setToolTipText("URL of where disk came from, can also be a local file path");
NameField.setText("Disk name");
NameField.setToolTipText("Name of disk -- if part of a series include side or disk number");
CategoryField.setText("Category > sub cat > sub cat");
CategoryField.setToolTipText("Category (use > marks to separate sub-category)");
DescriptionField.setColumns(20);
DescriptionField.setRows(5);
DescriptionField.setText("Description of disk goes here");
DescriptionPane.setViewportView(DescriptionField);
AuthorField.setText("Smith, John");
YearField.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1976", "1977", "1978", "1979", "1980", "1981", "1982", "1983", "1984", "1985", "1986", "1987", "1988", "1989", "1990", "1991", "1992", "1993", "1994", "1995", "1996", "1997", "1998", "1999", "2000", "2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015" }));
KeywordsField.setText("Keyword1, Keyword2, Keyword3");
KeywordsField.setToolTipText("Relevant keywords (use commas to separate multiple keywords)");
FavoriteField.setText("Show in favorites");
SaveButton.setText("Save");
SaveButton.setToolTipText("Save metadata changes");
SaveButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
SaveButtonActionPerformed(evt);
}
});
CancellationButton.setText("Close");
CancellationButton.setToolTipText("Abandon metadata changes and close");
CancellationButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
CancellationButtonActionPerformed(evt);
}
});
ReplaceButton.setText("Replace Disk");
ReplaceButton.setToolTipText("Abandon current disk image and download a new copy from the source URL");
ReplaceButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ReplaceButtonActionPerformed(evt);
}
});
InfoLabel.setText("Disk usage here");
InfoLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
CopyDiskButton.setText("Save copy of disk");
CopyDiskButton.setToolTipText("Create a local copy of the disk image on your hard drive");
CopyDiskButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
CopyDiskButtonActionPerformed(evt);
}
});
ScreenshotCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Screenshot", "Box (front)", "Box (back)" }));
ScreenshotCombo.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ScreenshotComboActionPerformed(evt);
}
});
PublisherField.setText("Publisher");
PublisherLabel.setText("By");
writeProtect.setText("Write Protect");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(NameLabel)
.addComponent(KeywordsLabel)
.addComponent(SourceLabel)
.addComponent(DescriptionLabel)
.addComponent(AuthorLabel)
.addGroup(layout.createSequentialGroup()
.addGap(5, 5, 5)
.addComponent(CategoryLabel))
.addComponent(PublishedLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(SourceField)
.addComponent(NameField)
.addComponent(DescriptionPane, javax.swing.GroupLayout.DEFAULT_SIZE, 319, Short.MAX_VALUE)
.addComponent(CategoryField, javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(YearField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(PublisherLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(PublisherField))
.addComponent(KeywordsField)
.addComponent(AuthorField)))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(ReplaceButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(CopyDiskButton))
.addGroup(layout.createSequentialGroup()
.addGap(112, 112, 112)
.addComponent(writeProtect, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(FavoriteField)))
.addGap(0, 56, Short.MAX_VALUE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(SaveButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(CancellationButton))
.addComponent(ScreenshotCombo, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(Screenshot, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(InfoLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(Screenshot, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ScreenshotCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(InfoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(CancellationButton)
.addComponent(SaveButton)
.addComponent(ReplaceButton)
.addComponent(CopyDiskButton)))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(NameLabel)
.addComponent(NameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(SourceField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(SourceLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(DescriptionLabel)
.addComponent(DescriptionPane, javax.swing.GroupLayout.DEFAULT_SIZE, 125, Short.MAX_VALUE))
.addGap(8, 8, 8)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(CategoryLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(CategoryField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(YearField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(PublishedLabel)
.addComponent(PublisherLabel)
.addComponent(PublisherField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(AuthorField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(AuthorLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(KeywordsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(KeywordsLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(writeProtect)
.addComponent(FavoriteField))
.addGap(36, 36, 36)))
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void SaveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SaveButtonActionPerformed
persist();
library.refreshUI();
// Emulator.getFrame().closeDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME);
}//GEN-LAST:event_SaveButtonActionPerformed
/**
* If confirmed, the current disk image will be wiped out and reloaded from
* the source if the source can still be found
*
* @param evt ignored
*/
private void ReplaceButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ReplaceButtonActionPerformed
if (!EmulatorUILogic.confirm("This will wipe out your local copy permanently. Only press OK if you are sure you want this to happen.")) {
return;
}
MediaFile f = library.cache.getCurrentFile(editingEntity, true);
library.cache.downloadImage(editingEntity, f, false);
}//GEN-LAST:event_ReplaceButtonActionPerformed
private void CopyDiskButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CopyDiskButtonActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_CopyDiskButtonActionPerformed
private void CancellationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CancellationButtonActionPerformed
if (EmulatorUILogic.confirm("Abandon unsaved changes? Are you sure?")) {
// Emulator.getFrame().closeDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME);
}
}//GEN-LAST:event_CancellationButtonActionPerformed
/**
* Look at what type of screenshot to show and present it if available.
*
* @param evt passed in but actually just ignored
*/
private void ScreenshotComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ScreenshotComboActionPerformed
}//GEN-LAST:event_ScreenshotComboActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTextField AuthorField;
private javax.swing.JLabel AuthorLabel;
private javax.swing.JButton CancellationButton;
private javax.swing.JTextField CategoryField;
private javax.swing.JLabel CategoryLabel;
private javax.swing.JButton CopyDiskButton;
private javax.swing.JTextArea DescriptionField;
private javax.swing.JLabel DescriptionLabel;
private javax.swing.JScrollPane DescriptionPane;
private javax.swing.JCheckBox FavoriteField;
private javax.swing.JLabel InfoLabel;
private javax.swing.JTextField KeywordsField;
private javax.swing.JLabel KeywordsLabel;
private javax.swing.JTextField NameField;
private javax.swing.JLabel NameLabel;
private javax.swing.JLabel PublishedLabel;
private javax.swing.JTextField PublisherField;
private javax.swing.JLabel PublisherLabel;
private javax.swing.JButton ReplaceButton;
private javax.swing.JButton SaveButton;
private javax.swing.JLabel Screenshot;
private javax.swing.JComboBox ScreenshotCombo;
private javax.swing.JTextField SourceField;
private javax.swing.JLabel SourceLabel;
private javax.swing.JComboBox YearField;
private javax.swing.JCheckBox writeProtect;
// End of variables declaration//GEN-END:variables
MediaEntry editingEntity;
void populate(MediaEntry entity) {
// TODO: Implement all fields
AuthorField.setText(entity.author);
// entity.type
// entity.auxtype
CategoryField.setText(entity.category);
DescriptionField.setText(entity.description);
FavoriteField.setSelected(entity.favorite);
KeywordsField.setText(joinKeywords(entity.keywords));
NameField.setText(entity.name);
PublisherField.setText(entity.publisher);
if (entity.boxBackURL == null) {
ScreenshotCombo.removeItem(BOX_BACK);
}
if (entity.boxFrontURL == null) {
ScreenshotCombo.removeItem(BOX_FRONT);
}
if (entity.screenshotURL == null) {
ScreenshotCombo.removeItem(SCREENSHOT);
}
if (ScreenshotCombo.getItemCount() == 0) {
Screenshot.setVisible(false);
ScreenshotCombo.setVisible(false);
}
SourceField.setText(entity.source);
writeProtect.setSelected(entity.writeProtected);
YearField.setSelectedItem(entity.year);
editingEntity = entity;
}
void persist() {
editingEntity.author = AuthorField.getText();
// entity.type
// entity.auxtype
editingEntity.category = CategoryField.getText();
editingEntity.description = DescriptionField.getText();
editingEntity.favorite = FavoriteField.isSelected();
editingEntity.keywords = splitKeywords(KeywordsField.getText());
editingEntity.name = NameField.getText();
editingEntity.publisher = PublisherField.getText();
editingEntity.source = SourceField.getText();
editingEntity.writeProtected = writeProtect.isSelected();
editingEntity.year = String.valueOf(YearField.getSelectedItem());
if (createMode) {
MediaCache.getLocalLibrary().add(editingEntity);
setCreate(false);
} else {
MediaCache.getLocalLibrary().update(editingEntity);
}
}
boolean createMode = false;
void setCreate(boolean b) {
createMode = b;
if (createMode) {
setName(CREATE_TITLE);
} else {
setName(EDIT_TITLE);
}
}
MediaLibraryUI library = null;
void setParentLibary(MediaLibraryUI library) {
this.library = library;
}
private String[] splitKeywords (String keywords) {
return keywords.split(KEYWORD_DELIMITER);
}
private String joinKeywords(String[] keywords) {
if (keywords == null) {
return "";
}
StringBuilder out = new StringBuilder();
for (String keyword : keywords) {
if (keyword.length() == 0) {
continue;
}
if (out.length() > 0) {
out.append(KEYWORD_DELIMITER);
}
out.append(keyword);
}
return out.toString();
}
}

View File

@ -1,124 +0,0 @@
/*
* Copyright (C) 2013 brobert.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package jace.library;
import jace.Emulator;
import jace.config.ConfigurableField;
import jace.config.Reconfigurable;
import jace.core.Card;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.Optional;
import javax.swing.JPanel;
/**
* Main entry point of the media library Serves as an interface between the UI
* and the media cache Also provides a touchpoint for emulator configuration
* options
*
* @author brobert
*/
public class MediaLibrary implements Reconfigurable {
private static MediaLibrary instance;
public static MediaLibrary getInstance() {
if (instance == null) {
instance = new MediaLibrary();
}
return instance;
}
//--------------------------------------------------------------------------
@ConfigurableField(category = "Library", defaultValue = "true", name = "Auto-add", description = "Automatically download and save local copies of disks when played.")
public static boolean CREATE_LOCAL_ON_LOAD = true;
@ConfigurableField(category = "Library", defaultValue = "true", name = "Keep local copy", description = "Automatically download and save local copies of disks when written.")
public static boolean CREATE_LOCAL_ON_SAVE = true;
@Override
public String getName() {
return "Media Library";
}
@Override
public String getShortName() {
return "media";
}
@Override
public void reconfigure() {
rebuildDriveList();
}
//--------------------------------------------------------------------------
MediaManagerUI userInterface;
public JPanel buildUserInterface() {
userInterface = new MediaManagerUI();
rebuildDriveList();
rebuildTabs();
return userInterface;
}
public void rebuildDriveList() {
if (userInterface == null) {
return;
}
userInterface.Drives.removeAll();
for (Optional<Card> card : Emulator.computer.memory.getAllCards()) {
card.filter(c -> c instanceof MediaConsumerParent).ifPresent(parent -> {
GridBagLayout layout = (GridBagLayout) userInterface.Drives.getLayout();
GridBagConstraints c = new GridBagConstraints();
for (MediaConsumer consumer : ((MediaConsumerParent) parent).getConsumers()) {
DriveIcon drive = new DriveIcon(consumer);
drive.setSize(100, 70);
drive.setPreferredSize(new Dimension(100, 70));
c.gridwidth = GridBagConstraints.REMAINDER;
layout.setConstraints(drive, c);
userInterface.Drives.add(drive);
}
});
}
userInterface.Drives.revalidate();
}
private void rebuildTabs() {
userInterface.Libraries.removeAll();
MediaCache localLibraryCache = MediaCache.getLocalLibrary();
MediaLibraryUI localLibrary = new MediaLibraryUI();
localLibrary.setName("Local");
localLibrary.setCache(localLibraryCache);
localLibrary.setLocal(true);
userInterface.Libraries.add(localLibrary);
userInterface.Libraries.revalidate();
}
public MediaEditUI buildEditInstance(MediaLibraryUI library, MediaEntry entry) {
MediaEditUI form = new MediaEditUI();
if (entry == null) {
// create form
form.setCreate(true);
form.populate(new MediaEntry());
} else {
form.setCreate(false);
form.populate(entry);
}
form.setParentLibary(library);
return form;
}
}

View File

@ -1,198 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.6" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="1"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="orderToolbar" min="-2" max="-2" attributes="0"/>
<Component id="tocPane" max="32767" attributes="0"/>
</Group>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="actionToolbar" min="-2" max="-2" attributes="0"/>
<Component id="titleLabel" min="-2" pref="261" max="-2" attributes="0"/>
<Component id="descriptionLabel" min="-2" pref="261" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="titlesScrollpane" pref="277" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="orderToolbar" alignment="0" min="-2" pref="25" max="-2" attributes="0"/>
<Component id="actionToolbar" alignment="0" min="-2" pref="25" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" attributes="0">
<Component id="titlesScrollpane" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="descriptionLabel" min="-2" pref="110" max="-2" attributes="0"/>
</Group>
<Component id="tocPane" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="tocPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTree" name="tocTree">
<Events>
<EventHandler event="valueChanged" listener="javax.swing.event.TreeSelectionListener" parameters="javax.swing.event.TreeSelectionEvent" handler="tocTreeValueChanged"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JToolBar" name="orderToolbar">
<Properties>
<Property name="rollover" type="boolean" value="true"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="orderByLabel">
<Properties>
<Property name="text" type="java.lang.String" value="Order By:"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="orderByCombo">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="7">
<StringItem index="0" value="Name"/>
<StringItem index="1" value="Favorites"/>
<StringItem index="2" value="Recently Used"/>
<StringItem index="3" value="Category"/>
<StringItem index="4" value="Source"/>
<StringItem index="5" value="Keyword"/>
<StringItem index="6" value="Author"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="orderByComboActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JToolBar" name="actionToolbar">
<Properties>
<Property name="rollover" type="boolean" value="true"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<SubComponents>
<Component class="javax.swing.JButton" name="CreateNew">
<Properties>
<Property name="text" type="java.lang.String" value="Create"/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="verticalTextPosition" type="int" value="3"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="CreateNewActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="ViewEdit">
<Properties>
<Property name="text" type="java.lang.String" value="View"/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="verticalTextPosition" type="int" value="3"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="ViewEditActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="Remove">
<Properties>
<Property name="text" type="java.lang.String" value="Remove"/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="verticalTextPosition" type="int" value="3"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="RemoveActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="Favorite">
<Properties>
<Property name="text" type="java.lang.String" value="Favorite"/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="verticalTextPosition" type="int" value="3"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="FavoriteActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JScrollPane" name="titlesScrollpane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="titlesList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
<StringArray count="1">
<StringItem index="0" value="Software titles listed here"/>
</StringArray>
</Property>
<Property name="selectionMode" type="int" value="0"/>
<Property name="dragEnabled" type="boolean" value="true"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="titleLabel">
<Properties>
<Property name="text" type="java.lang.String" value="SoftwareTitle"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="descriptionLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font component="descriptionLabel" italic="true" property="font" relativeSize="true" size="0"/>
</FontInfo>
</Property>
<Property name="horizontalAlignment" type="int" value="2"/>
<Property name="text" type="java.lang.String" value="Software Description Here"/>
<Property name="verticalAlignment" type="int" value="1"/>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -1,471 +0,0 @@
/*
* Copyright (C) 2013 brobert.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package jace.library;
import jace.Emulator;
import jace.EmulatorUILogic;
import static jace.EmulatorUILogic.MEDIA_MANAGER_EDIT_DIALOG_NAME;
import static jace.EmulatorUILogic.MEDIA_MANAGER_DIALOG_NAME;
import jace.core.Utility;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
/**
*
* @author brobert
*/
public class MediaLibraryUI extends javax.swing.JPanel {
public static final String EMPTY_VALUE = "_EMPTY_";
public static final String MISCELLANEOUS = "Misc.";
/**
* Creates new form MediaLibraryUI
*/
public MediaLibraryUI() {
initComponents();
titlesList.setTransferHandler(new DiskTransferHandler());
titlesList.setDragEnabled(true);
titlesList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if (e.getClickCount() > 1) {
ViewEditActionPerformed(null);
}
}
});
setDropTarget(new DropTarget() {
public synchronized void drop(DropTargetDropEvent evt) {
try {
evt.acceptDrop(DnDConstants.ACTION_COPY);
List<File> droppedFiles = null;
try {
droppedFiles = (List<File>) evt.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
} catch (ClassCastException e) {
return;
}
boolean added = false;
for (File file : droppedFiles) {
MediaEntry entry = new MediaEntry();
entry.name = file.getName();
entry.source = file.toURI().toURL().toExternalForm();
entry.type = DiskType.determineType(file);
entry.description = "Added via drag-and-drop to media library";
if (null == MediaCache.getLocalLibrary().findLocalEntry(entry)) {
MediaCache.getLocalLibrary().add(entry);
added = true;
}
}
if (added) {
refreshUI();
}
} catch (Exception ex) {
ex.printStackTrace(System.err);
Utility.gripe("Could not add file to library: " + ex.getMessage());
}
}
});
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
tocPane = new javax.swing.JScrollPane();
tocTree = new javax.swing.JTree();
orderToolbar = new javax.swing.JToolBar();
orderByLabel = new javax.swing.JLabel();
orderByCombo = new javax.swing.JComboBox();
actionToolbar = new javax.swing.JToolBar();
CreateNew = new javax.swing.JButton();
ViewEdit = new javax.swing.JButton();
Remove = new javax.swing.JButton();
Favorite = new javax.swing.JButton();
titlesScrollpane = new javax.swing.JScrollPane();
titlesList = new javax.swing.JList();
titleLabel = new javax.swing.JLabel();
descriptionLabel = new javax.swing.JLabel();
tocTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
tocTreeValueChanged(evt);
}
});
tocPane.setViewportView(tocTree);
orderToolbar.setRollover(true);
orderByLabel.setText("Order By:");
orderToolbar.add(orderByLabel);
orderByCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Name", "Favorites", "Recently Used", "Category", "Source", "Keyword", "Author" }));
orderByCombo.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
orderByComboActionPerformed(evt);
}
});
orderToolbar.add(orderByCombo);
actionToolbar.setRollover(true);
CreateNew.setText("Create");
CreateNew.setFocusable(false);
CreateNew.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
CreateNew.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
CreateNew.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
CreateNewActionPerformed(evt);
}
});
actionToolbar.add(CreateNew);
ViewEdit.setText("View");
ViewEdit.setFocusable(false);
ViewEdit.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
ViewEdit.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
ViewEdit.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ViewEditActionPerformed(evt);
}
});
actionToolbar.add(ViewEdit);
Remove.setText("Remove");
Remove.setFocusable(false);
Remove.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
Remove.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
Remove.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
RemoveActionPerformed(evt);
}
});
actionToolbar.add(Remove);
Favorite.setText("Favorite");
Favorite.setFocusable(false);
Favorite.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
Favorite.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
Favorite.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
FavoriteActionPerformed(evt);
}
});
actionToolbar.add(Favorite);
titlesList.setModel(new javax.swing.AbstractListModel() {
String[] strings = { "Software titles listed here" };
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; }
});
titlesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
titlesList.setDragEnabled(true);
titlesScrollpane.setViewportView(titlesList);
titleLabel.setText("SoftwareTitle");
descriptionLabel.setFont(descriptionLabel.getFont().deriveFont((descriptionLabel.getFont().getStyle() | java.awt.Font.ITALIC)));
descriptionLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
descriptionLabel.setText("Software Description Here");
descriptionLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(orderToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(tocPane))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(3, 3, 3)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(actionToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(titleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(layout.createSequentialGroup()
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(titlesScrollpane))))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(orderToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(actionToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(titlesScrollpane)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(titleLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(descriptionLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(tocPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)))
);
}// </editor-fold>//GEN-END:initComponents
private void ViewEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ViewEditActionPerformed
if (getSelectedEntry() == null) {
return;
}
System.out.println(getSelectedEntry().name);
// Emulator.getFrame().registerModalDialog(
// MediaLibrary.getInstance().buildEditInstance(this, getSelectedEntry()),
// MEDIA_MANAGER_EDIT_DIALOG_NAME,
// MEDIA_MANAGER_DIALOG_NAME, true);
// Emulator.getFrame().showDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME);
}//GEN-LAST:event_ViewEditActionPerformed
private void RemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RemoveActionPerformed
MediaEntry selection = getSelectedEntry();
if (selection == null) {
return;
}
String message = "Are you sure you want to remove " + selection.name + " from the library? This cannot be undone!";
if (!EmulatorUILogic.confirm(message)) {
return;
}
cache.remove(selection);
refreshUI();
}//GEN-LAST:event_RemoveActionPerformed
private void CreateNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CreateNewActionPerformed
// Emulator.getFrame().registerModalDialog(
// MediaLibrary.getInstance().buildEditInstance(this, null),
// MEDIA_MANAGER_EDIT_DIALOG_NAME,
// MEDIA_MANAGER_DIALOG_NAME, true);
// Emulator.getFrame().showDialog(MEDIA_MANAGER_EDIT_DIALOG_NAME);
}//GEN-LAST:event_CreateNewActionPerformed
private void FavoriteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FavoriteActionPerformed
MediaEntry selection = getSelectedEntry();
if (selection == null) {
return;
}
selection.favorite = true;
cache.update(selection);
}//GEN-LAST:event_FavoriteActionPerformed
private void orderByComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_orderByComboActionPerformed
updateTOCTree();
}//GEN-LAST:event_orderByComboActionPerformed
private void tocTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_tocTreeValueChanged
titlesList.removeAll();
TreeModel model = tocTree.getModel();
if (!(model instanceof TocTreeModel)) {
return;
}
TocTreeModel tocModel = (TocTreeModel) model;
Set<Long> allEntries = tocModel.getEntries(evt.getPath().getLastPathComponent());
if (allEntries == null) {
return;
}
Vector v = new Vector();
for (Long l : allEntries) {
v.add(cache.mediaLookup.get(l));
}
titlesList.setListData(v);
}//GEN-LAST:event_tocTreeValueChanged
// Variables declaration - do not modify//GEN-BEGIN:variables
public javax.swing.JButton CreateNew;
public javax.swing.JButton Favorite;
public javax.swing.JButton Remove;
public javax.swing.JButton ViewEdit;
public javax.swing.JToolBar actionToolbar;
public javax.swing.JLabel descriptionLabel;
public javax.swing.JComboBox orderByCombo;
public javax.swing.JLabel orderByLabel;
public javax.swing.JToolBar orderToolbar;
public javax.swing.JLabel titleLabel;
public javax.swing.JList titlesList;
public javax.swing.JScrollPane titlesScrollpane;
public javax.swing.JScrollPane tocPane;
public javax.swing.JTree tocTree;
// End of variables declaration//GEN-END:variables
MediaCache cache;
public void setCache(MediaCache libraryCache) {
cache = libraryCache;
updateTOCTree();
}
boolean localLibrary;
public void setLocal(boolean b) {
localLibrary = b;
}
public boolean isLocal() {
return localLibrary;
}
private MediaEntry getSelectedEntry() {
Object sel = titlesList.getSelectedValue();
if (sel == null || !(sel instanceof MediaEntry)) {
return null;
}
return (MediaEntry) sel;
}
public void refreshUI() {
//TODO: Preserve selections in toc tree and media title list!
updateTOCTree();
}
public static interface tocSortModel {
public TreeModel buildModel(MediaCache cache);
}
public static enum tocOptions {
Name("Name", new tocSortModel() {
public TreeModel buildModel(MediaCache cache) {
Set<String> names = cache.nameLookup.keySet();
TocTreeModel model = new TocTreeModel();
model.name = "All By Name";
for (String name : names) {
if (name == null || name.length() == 0) {
name = EMPTY_VALUE;
}
String letter = name.toUpperCase().substring(0, 1);
model.addItems(letter, name, cache.nameLookup.get(name));
}
model.twoLevel = false;
return model;
}
}),
Favorites(
"Favorites", new tocSortModel() {
public TreeModel buildModel(MediaCache cache) {
Set<String> names = cache.nameLookup.keySet();
TocTreeModel model = new TocTreeModel();
model.name = "Favorites By Name";
for (String name : names) {
// Filter out only the favorites
Set<Long> entries = cache.nameLookup.get(name);
entries.retainAll(cache.favorites);
if (entries.isEmpty()) {
continue;
}
if (name == null || name.length() == 0) {
name = EMPTY_VALUE;
}
String letter = name.toUpperCase().substring(0, 1);
model.addItems(letter, name, entries);
}
model.twoLevel = false;
return model;
}
}),
Recently_Used("Recently Used", new tocSortModel() {
public TreeModel buildModel(MediaCache cache) {
TreeModel model = new DefaultTreeModel(null, true);
return model;
}
}),
Category("Category", new tocSortModel() {
public TreeModel buildModel(MediaCache cache) {
Set<String> names = cache.categoryLookup.keySet();
TocTreeModel model = new TocTreeModel();
model.name = "All By Category";
for (String name : names) {
if (name == null || name.length() == 0) {
name = EMPTY_VALUE;
}
String[] categories = name.split(":|/");
String sub = (categories.length > 1 ? categories[1] : MISCELLANEOUS);
model.addItems(categories[0], sub, cache.nameLookup.get(name));
}
return model;
}
}),
Source("Source", new tocSortModel() {
public TreeModel buildModel(MediaCache cache) {
TreeModel model = new DefaultTreeModel(null, true);
return model;
}
}),
Keyword("Keyword", new tocSortModel() {
public TreeModel buildModel(MediaCache cache) {
Set<String> names = cache.keywordLookup.keySet();
TocTreeModel model = new TocTreeModel();
model.name = "All By Keyword";
for (String name : names) {
if (name == null || name.length() == 0) {
name = EMPTY_VALUE;
}
String letter = name.toUpperCase().substring(0, 1);
model.addItems(letter, name, cache.keywordLookup.get(name));
}
return model;
}
}),
Author("Author", new tocSortModel() {
public TreeModel buildModel(MediaCache cache) {
TreeModel model = new DefaultTreeModel(null, true);
return model;
}
});
String alternate;
public tocSortModel factory;
tocOptions(String alt, tocSortModel modelFactory) {
alternate = alt;
factory = modelFactory;
}
public static tocOptions fromString(String str) {
try {
return tocOptions.valueOf(str);
} catch (Throwable t) {
for (tocOptions option : tocOptions.values()) {
if (option.alternate.equalsIgnoreCase(str)) {
return option;
}
}
}
return null;
}
};
private void updateTOCTree() {
String order = String.valueOf(orderByCombo.getSelectedItem());
tocOptions sortOption = tocOptions.fromString(order);
tocTree.setModel(sortOption.factory.buildModel(cache));
}
}

View File

@ -1,202 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.8" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="1"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="Libraries" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="Drives" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="4" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="Libraries" pref="0" max="32767" attributes="0"/>
<Component id="Drives" alignment="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JTabbedPane" name="Libraries">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
<SubComponents>
<Component class="jace.library.MediaLibraryUI" name="mediaLibraryUI2">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Local">
<Property name="tabTitle" type="java.lang.String" value="Local"/>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
</Component>
<Component class="jace.library.MediaLibraryUI" name="mediaLibraryUI3">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Virtual II">
<Property name="tabTitle" type="java.lang.String" value="Virtual II"/>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JPanel" name="addLibraryTab">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Add New Library">
<Property name="tabTitle" type="java.lang.String" value="Add New Library"/>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="libraryAddInstructionsLabel" pref="0" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="librarySourceLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="libraryPathField" pref="370" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="addLibraryButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="libraryAddInstructionsLabel" min="-2" pref="63" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="libraryPathField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="librarySourceLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="addLibraryButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="269" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JTextField" name="libraryPathField">
<Properties>
<Property name="text" type="java.lang.String" value="jTextField1"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="libraryPathFieldActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="librarySourceLabel">
<Properties>
<Property name="text" type="java.lang.String" value="Source"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="libraryAddInstructionsLabel">
<Properties>
<Property name="text" type="java.lang.String" value="&lt;html&gt;&lt;p&gt;Either type in the URL or path to the source, or drag it from another window (file manager or web browser) -- The source should be the path to the XML catalog, not just the path to the main website.&lt;/p&gt;"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="addLibraryButton">
<Properties>
<Property name="text" type="java.lang.String" value="Add"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addLibraryButtonActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="Drives">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[100, 430]"/>
</Property>
</Properties>
<LayoutCode>
<CodeStatement>
<CodeExpression id="1_DrivesLayout">
<CodeVariable name="DrivesLayout" type="4096" declaredType="java.awt.GridBagLayout"/>
<ExpressionOrigin>
<ExpressionProvider type="CodeConstructor">
<CodeConstructor class="java.awt.GridBagLayout" parameterTypes=""/>
</ExpressionProvider>
</ExpressionOrigin>
</CodeExpression>
<StatementProvider type="CodeExpression">
<CodeExpression id="1_DrivesLayout"/>
</StatementProvider>
</CodeStatement>
<CodeStatement>
<CodeExpression id="1_DrivesLayout"/>
<StatementProvider type="CodeField">
<CodeField name="columnWidths" class="java.awt.GridBagLayout"/>
</StatementProvider>
<Parameters>
<CodeExpression id="2">
<ExpressionOrigin>
<Value type="[I" editor="org.netbeans.modules.form.layoutsupport.delegates.GridBagLayoutSupport$IntArrayPropertyEditor">
<PropertyValue value="[1]"/>
</Value>
</ExpressionOrigin>
</CodeExpression>
</Parameters>
</CodeStatement>
<CodeStatement>
<CodeExpression id="1_DrivesLayout"/>
<StatementProvider type="CodeField">
<CodeField name="rowHeights" class="java.awt.GridBagLayout"/>
</StatementProvider>
<Parameters>
<CodeExpression id="3">
<ExpressionOrigin>
<Value type="[I" editor="org.netbeans.modules.form.layoutsupport.delegates.GridBagLayoutSupport$IntArrayPropertyEditor">
<PropertyValue value="[10]"/>
</Value>
</ExpressionOrigin>
</CodeExpression>
</Parameters>
</CodeStatement>
<CodeStatement>
<CodeExpression id="4_Drives">
<CodeVariable name="Drives" type="8193" declaredType="javax.swing.JPanel"/>
<ExpressionOrigin>
<ExpressionProvider type="ComponentRef">
<ComponentRef name="Drives"/>
</ExpressionProvider>
</ExpressionOrigin>
</CodeExpression>
<StatementProvider type="CodeMethod">
<CodeMethod name="setLayout" class="java.awt.Container" parameterTypes="java.awt.LayoutManager"/>
</StatementProvider>
<Parameters>
<CodeExpression id="1_DrivesLayout"/>
</Parameters>
</CodeStatement>
</LayoutCode>
</Container>
</SubComponents>
</Form>

View File

@ -1,148 +0,0 @@
/*
* Copyright (C) 2013 brobert.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package jace.library;
/**
*
* @author brobert
*/
public class MediaManagerUI extends javax.swing.JPanel {
/**
* Creates new form MediaManagerUI
*/
public MediaManagerUI() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
Libraries = new javax.swing.JTabbedPane();
mediaLibraryUI2 = new jace.library.MediaLibraryUI();
mediaLibraryUI3 = new jace.library.MediaLibraryUI();
addLibraryTab = new javax.swing.JPanel();
libraryPathField = new javax.swing.JTextField();
librarySourceLabel = new javax.swing.JLabel();
libraryAddInstructionsLabel = new javax.swing.JLabel();
addLibraryButton = new javax.swing.JButton();
Drives = new javax.swing.JPanel();
Libraries.addTab("Local", mediaLibraryUI2);
Libraries.addTab("Virtual II", mediaLibraryUI3);
libraryPathField.setText("jTextField1");
libraryPathField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
libraryPathFieldActionPerformed(evt);
}
});
librarySourceLabel.setText("Source");
libraryAddInstructionsLabel.setText("<html><p>Either type in the URL or path to the source, or drag it from another window (file manager or web browser) -- The source should be the path to the XML catalog, not just the path to the main website.</p>");
addLibraryButton.setText("Add");
addLibraryButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
addLibraryButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout addLibraryTabLayout = new javax.swing.GroupLayout(addLibraryTab);
addLibraryTab.setLayout(addLibraryTabLayout);
addLibraryTabLayout.setHorizontalGroup(
addLibraryTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(addLibraryTabLayout.createSequentialGroup()
.addContainerGap()
.addGroup(addLibraryTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(libraryAddInstructionsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addGroup(addLibraryTabLayout.createSequentialGroup()
.addComponent(librarySourceLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(libraryPathField, javax.swing.GroupLayout.DEFAULT_SIZE, 370, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(addLibraryButton)))
.addContainerGap())
);
addLibraryTabLayout.setVerticalGroup(
addLibraryTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(addLibraryTabLayout.createSequentialGroup()
.addContainerGap()
.addComponent(libraryAddInstructionsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addGroup(addLibraryTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(libraryPathField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(librarySourceLabel)
.addComponent(addLibraryButton))
.addContainerGap(269, Short.MAX_VALUE))
);
Libraries.addTab("Add New Library", addLibraryTab);
Drives.setMinimumSize(new java.awt.Dimension(100, 430));
java.awt.GridBagLayout DrivesLayout = new java.awt.GridBagLayout();
DrivesLayout.columnWidths = new int[] {1};
DrivesLayout.rowHeights = new int[] {10};
Drives.setLayout(DrivesLayout);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(Libraries)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(Drives, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(4, 4, 4))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(Libraries, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
.addComponent(Drives, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
private void libraryPathFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_libraryPathFieldActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_libraryPathFieldActionPerformed
private void addLibraryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addLibraryButtonActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_addLibraryButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
public javax.swing.JPanel Drives;
public javax.swing.JTabbedPane Libraries;
public javax.swing.JButton addLibraryButton;
public javax.swing.JPanel addLibraryTab;
public javax.swing.JLabel libraryAddInstructionsLabel;
public javax.swing.JTextField libraryPathField;
public javax.swing.JLabel librarySourceLabel;
public jace.library.MediaLibraryUI mediaLibraryUI2;
public jace.library.MediaLibraryUI mediaLibraryUI3;
// End of variables declaration//GEN-END:variables
}

View File

@ -168,7 +168,7 @@ public class Row {
ImageIcon getIcon() { ImageIcon getIcon() {
if (icon == null) { if (icon == null) {
if (value >= 0) { if (value >= 0) {
icon = Utility.loadIcon("ayenvelope"+value+".png"); // icon = Utility.loadIcon("ayenvelope"+value+".png");
} else { } else {
icon = new ImageIcon(new BufferedImage(64, 12,BufferedImage.TYPE_4BYTE_ABGR)); icon = new ImageIcon(new BufferedImage(64, 12,BufferedImage.TYPE_4BYTE_ABGR));
} }

View File

@ -10,7 +10,11 @@
<AnchorPane id="AnchorPane" fx:id="rootPane" prefHeight="384.0" prefWidth="560.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="jace.JaceUIController"> <AnchorPane id="AnchorPane" fx:id="rootPane" prefHeight="384.0" prefWidth="560.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="jace.JaceUIController">
<children> <children>
<Region fx:id="notificationRegion" prefHeight="50.0" prefWidth="510.0" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="5.0" /> <StackPane fx:id="stackPane" prefHeight="384.0" prefWidth="560.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<ImageView fx:id="appleScreen" fitHeight="384.0" fitWidth="560.0" pickOnBounds="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> <children>
<ImageView fx:id="appleScreen" fitHeight="384.0" fitWidth="560.0" pickOnBounds="true" />
<HBox fx:id="notificationBox" alignment="BOTTOM_RIGHT" blendMode="SCREEN" fillHeight="false" maxHeight="45.0" prefHeight="45.0" prefWidth="560.0" StackPane.alignment="BOTTOM_CENTER" />
</children>
</StackPane>
</children> </children>
</AnchorPane> </AnchorPane>

View File

@ -2,12 +2,15 @@
-fx-font-weight: bold; -fx-font-weight: bold;
} }
.setting-row {
-fx-padding: 5 0 0 4;
}
.setting-label, .setting-keyboard-shortcut { .setting-label, .setting-keyboard-shortcut {
-fx-padding: 5 0 0 4;
-fx-allignment: center-left; -fx-allignment: center-left;
} }
.setting-keyboard-shortcut { .setting-keyboard-shortcut {
-fx-graphic: "/jace/data/icon_keyboard.gif"; -fx-graphic: "/jace/data/icon_keyboard.gif";
-fx-graphic-text-gap: 2; -fx-graphic-text-gap: 2;
} }