Merge remote-tracking branch 'plaa/kruland-integration' into
kruland-integration-defaults Conflicts: core/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java
This commit is contained in:
commit
9ae80e5a84
@ -4,6 +4,7 @@ import java.io.File;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.EventListener;
|
||||||
|
|
||||||
import net.sf.openrocket.appearance.DecalImage;
|
import net.sf.openrocket.appearance.DecalImage;
|
||||||
import net.sf.openrocket.document.Attachment;
|
import net.sf.openrocket.document.Attachment;
|
||||||
@ -42,4 +43,14 @@ class ResourceDecalImage implements DecalImage {
|
|||||||
return this.hashCode() - a.hashCode();
|
return this.hashCode() - a.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addChangeListener(EventListener listener) {
|
||||||
|
//Unimplemented, this can not change
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeChangeListener(EventListener listener) {
|
||||||
|
//Unimplemented, this can not change
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,9 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
public interface Attachment extends Comparable<Attachment> {
|
import net.sf.openrocket.util.ChangeSource;
|
||||||
|
|
||||||
|
public interface Attachment extends Comparable<Attachment>, ChangeSource {
|
||||||
|
|
||||||
public abstract String getName();
|
public abstract String getName();
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import java.io.InputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.EventListener;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -19,7 +20,11 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import net.sf.openrocket.appearance.DecalImage;
|
import net.sf.openrocket.appearance.DecalImage;
|
||||||
|
import net.sf.openrocket.document.attachments.BaseAttachment;
|
||||||
import net.sf.openrocket.document.attachments.FileSystemAttachment;
|
import net.sf.openrocket.document.attachments.FileSystemAttachment;
|
||||||
|
import net.sf.openrocket.gui.watcher.FileWatcher;
|
||||||
|
import net.sf.openrocket.gui.watcher.WatchEvent;
|
||||||
|
import net.sf.openrocket.gui.watcher.WatchService;
|
||||||
import net.sf.openrocket.logging.LogHelper;
|
import net.sf.openrocket.logging.LogHelper;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.BugException;
|
import net.sf.openrocket.util.BugException;
|
||||||
@ -28,12 +33,33 @@ import net.sf.openrocket.util.FileUtils;
|
|||||||
public class DecalRegistry {
|
public class DecalRegistry {
|
||||||
private static LogHelper log = Application.getLogger();
|
private static LogHelper log = Application.getLogger();
|
||||||
|
|
||||||
DecalRegistry() {
|
private WatchService watchService = Application.getWatchService();
|
||||||
|
|
||||||
|
DecalRegistry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, DecalImageImpl> registeredDecals = new HashMap<String, DecalImageImpl>();
|
private Map<String, DecalImageImpl> registeredDecals = new HashMap<String, DecalImageImpl>();
|
||||||
|
|
||||||
|
public DecalImage makeUniqueImage(DecalImage original) {
|
||||||
|
|
||||||
|
if (!(original instanceof DecalImageImpl)) {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
DecalImageImpl o = (DecalImageImpl) original;
|
||||||
|
|
||||||
|
DecalImageImpl newDecal = o.clone();
|
||||||
|
|
||||||
|
String newName = makeUniqueName(o.getName());
|
||||||
|
|
||||||
|
newDecal.name = newName;
|
||||||
|
|
||||||
|
registeredDecals.put(newName, newDecal);
|
||||||
|
|
||||||
|
return newDecal;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public DecalImage getDecalImage(Attachment attachment) {
|
public DecalImage getDecalImage(Attachment attachment) {
|
||||||
String decalName = attachment.getName();
|
String decalName = attachment.getName();
|
||||||
DecalImageImpl d;
|
DecalImageImpl d;
|
||||||
@ -73,7 +99,7 @@ public class DecalRegistry {
|
|||||||
return decals;
|
return decals;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DecalImageImpl implements DecalImage {
|
public class DecalImageImpl implements DecalImage, Cloneable {
|
||||||
|
|
||||||
private final Attachment delegate;
|
private final Attachment delegate;
|
||||||
|
|
||||||
@ -94,15 +120,61 @@ public class DecalRegistry {
|
|||||||
return name != null ? name : delegate.getName();
|
return name != null ? name : delegate.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns an InputStream backed by a byte[] containing the decal pixels.
|
||||||
|
* If it reads in the bytes from an actual file, the underlying file is closed.
|
||||||
|
*
|
||||||
|
* @return InputStream containing byte[] of the image
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public InputStream getBytes() throws FileNotFoundException, IOException {
|
public InputStream getBytes() throws FileNotFoundException, IOException {
|
||||||
return DecalRegistry.getDecal(this);
|
// First check if the decal is located on the file system
|
||||||
|
File exportedFile = getFileSystemLocation();
|
||||||
|
if (exportedFile != null) {
|
||||||
|
InputStream rawIs = new FileInputStream(exportedFile);
|
||||||
|
try {
|
||||||
|
byte[] bytes = FileUtils.readBytes(rawIs);
|
||||||
|
return new ByteArrayInputStream(bytes);
|
||||||
|
} finally {
|
||||||
|
rawIs.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return delegate.getBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exportImage(File file, boolean watchForChanges) throws IOException {
|
public void exportImage(File file, boolean watchForChanges) throws IOException {
|
||||||
DecalRegistry.exportDecal(this, file);
|
try {
|
||||||
|
InputStream is = getBytes();
|
||||||
|
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
|
||||||
|
|
||||||
|
FileUtils.copy(is, os);
|
||||||
|
|
||||||
|
is.close();
|
||||||
|
os.close();
|
||||||
|
|
||||||
this.fileSystemLocation = file;
|
this.fileSystemLocation = file;
|
||||||
|
|
||||||
|
if (watchForChanges) {
|
||||||
|
watchService.register(new FileWatcher(this.fileSystemLocation) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEvent(WatchEvent evt) {
|
||||||
|
((BaseAttachment) DecalImageImpl.this.delegate).fireChangeEvent();
|
||||||
|
System.out.println(this.getFile() + " has changed");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException iex) {
|
||||||
|
throw new BugException(iex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File getFileSystemLocation() {
|
File getFileSystemLocation() {
|
||||||
@ -126,50 +198,24 @@ public class DecalRegistry {
|
|||||||
return getName().compareTo(o.getName());
|
return getName().compareTo(o.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DecalImageImpl clone() {
|
||||||
|
DecalImageImpl clone = new DecalImageImpl(this.delegate);
|
||||||
|
clone.fileSystemLocation = this.fileSystemLocation;
|
||||||
|
|
||||||
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* This function returns an InputStream backed by a byte[] containing the decal pixels.
|
public void addChangeListener(EventListener listener) {
|
||||||
* If it reads in the bytes from an actual file, the underlying file is closed.
|
delegate.addChangeListener(listener);
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
* @return
|
|
||||||
* @throws FileNotFoundException
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private static InputStream getDecal(DecalImageImpl decal) throws FileNotFoundException, IOException {
|
|
||||||
|
|
||||||
// First check if the decal is located on the file system
|
|
||||||
File exportedFile = decal.getFileSystemLocation();
|
|
||||||
if (exportedFile != null) {
|
|
||||||
InputStream rawIs = new FileInputStream(exportedFile);
|
|
||||||
try {
|
|
||||||
byte[] bytes = FileUtils.readBytes(rawIs);
|
|
||||||
return new ByteArrayInputStream(bytes);
|
|
||||||
} finally {
|
|
||||||
rawIs.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeChangeListener(EventListener listener) {
|
||||||
|
delegate.removeChangeListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
return decal.delegate.getBytes();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void exportDecal(DecalImageImpl decal, File selectedFile) throws IOException {
|
|
||||||
|
|
||||||
try {
|
|
||||||
InputStream is = decal.getBytes();
|
|
||||||
OutputStream os = new BufferedOutputStream(new FileOutputStream(selectedFile));
|
|
||||||
|
|
||||||
FileUtils.copy(is, os);
|
|
||||||
|
|
||||||
is.close();
|
|
||||||
os.close();
|
|
||||||
|
|
||||||
} catch (IOException iex) {
|
|
||||||
throw new BugException(iex);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,14 +249,17 @@ public class DecalRegistry {
|
|||||||
* group(3) = "null"
|
* group(3) = "null"
|
||||||
* group(4) = "png"
|
* group(4) = "png"
|
||||||
*/
|
*/
|
||||||
private static final Pattern fileNamePattern = Pattern.compile("(.*?)( \\((\\d+)\\)\\)?+)?\\.(\\w*)");
|
private static final Pattern fileNamePattern = Pattern.compile("(.*?)( \\((\\d+)\\)+)?\\.(\\w*)");
|
||||||
private static final int BASE_NAME_INDEX = 1;
|
private static final int BASE_NAME_INDEX = 1;
|
||||||
private static final int NUMBER_INDEX = 3;
|
private static final int NUMBER_INDEX = 3;
|
||||||
private static final int EXTENSION_INDEX = 4;
|
private static final int EXTENSION_INDEX = 4;
|
||||||
|
|
||||||
private String makeUniqueName(String name) {
|
private String makeUniqueName(String name) {
|
||||||
|
|
||||||
String newName = "decals/" + name;
|
String newName = name;
|
||||||
|
if (!newName.startsWith("decals/")) {
|
||||||
|
newName = "decals/" + name;
|
||||||
|
}
|
||||||
String basename = "";
|
String basename = "";
|
||||||
String extension = "";
|
String extension = "";
|
||||||
Matcher nameMatcher = fileNamePattern.matcher(newName);
|
Matcher nameMatcher = fileNamePattern.matcher(newName);
|
||||||
|
|||||||
@ -3,11 +3,14 @@ package net.sf.openrocket.document;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.sf.openrocket.appearance.Appearance;
|
||||||
|
import net.sf.openrocket.appearance.Decal;
|
||||||
import net.sf.openrocket.appearance.DecalImage;
|
import net.sf.openrocket.appearance.DecalImage;
|
||||||
import net.sf.openrocket.document.events.DocumentChangeEvent;
|
import net.sf.openrocket.document.events.DocumentChangeEvent;
|
||||||
import net.sf.openrocket.document.events.DocumentChangeListener;
|
import net.sf.openrocket.document.events.DocumentChangeListener;
|
||||||
@ -18,6 +21,7 @@ import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
|||||||
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
|
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
|
||||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.simulation.FlightDataType;
|
import net.sf.openrocket.simulation.FlightDataType;
|
||||||
import net.sf.openrocket.simulation.customexpression.CustomExpression;
|
import net.sf.openrocket.simulation.customexpression.CustomExpression;
|
||||||
import net.sf.openrocket.simulation.listeners.SimulationListener;
|
import net.sf.openrocket.simulation.listeners.SimulationListener;
|
||||||
@ -206,6 +210,31 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int countDecalUsage(DecalImage img) {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
Iterator<RocketComponent> it = rocket.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
RocketComponent comp = it.next();
|
||||||
|
Appearance a = comp.getAppearance();
|
||||||
|
if (a == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Decal d = a.getTexture();
|
||||||
|
if (d == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (img.equals(d.getImage())) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DecalImage makeUniqueDecal(DecalImage img) {
|
||||||
|
return decalRegistry.makeUniqueImage(img);
|
||||||
|
}
|
||||||
|
|
||||||
public DecalImage getDecalImage(Attachment a) {
|
public DecalImage getDecalImage(Attachment a) {
|
||||||
return decalRegistry.getDecalImage(a);
|
return decalRegistry.getDecalImage(a);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,9 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import net.sf.openrocket.document.Attachment;
|
import net.sf.openrocket.document.Attachment;
|
||||||
|
import net.sf.openrocket.util.AbstractChangeSource;
|
||||||
|
|
||||||
public abstract class BaseAttachment implements Attachment {
|
public abstract class BaseAttachment extends AbstractChangeSource implements Attachment {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
@ -36,5 +37,9 @@ public abstract class BaseAttachment implements Attachment {
|
|||||||
return getName();
|
return getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fireChangeEvent() {
|
||||||
|
super.fireChangeEvent();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
25
core/src/net/sf/openrocket/file/AttachmentUtils.java
Normal file
25
core/src/net/sf/openrocket/file/AttachmentUtils.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package net.sf.openrocket.file;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import net.sf.openrocket.document.Attachment;
|
||||||
|
import net.sf.openrocket.util.FileUtils;
|
||||||
|
|
||||||
|
public abstract class AttachmentUtils {
|
||||||
|
|
||||||
|
public static void exportAttachment(Attachment a, File outFile) throws IOException {
|
||||||
|
InputStream is = a.getBytes();
|
||||||
|
OutputStream os = new BufferedOutputStream(new FileOutputStream(outFile));
|
||||||
|
|
||||||
|
FileUtils.copy(is, os);
|
||||||
|
|
||||||
|
is.close();
|
||||||
|
os.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,6 +16,7 @@ import javax.swing.JPanel;
|
|||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import net.sf.openrocket.appearance.DecalImage;
|
import net.sf.openrocket.appearance.DecalImage;
|
||||||
import net.sf.openrocket.document.OpenRocketDocument;
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
|
import net.sf.openrocket.file.AttachmentUtils;
|
||||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
@ -78,10 +79,10 @@ public class ExportDecalDialog extends JDialog {
|
|||||||
private void export(DecalImage decal, File selectedFile) {
|
private void export(DecalImage decal, File selectedFile) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
decal.exportImage(selectedFile, false);
|
AttachmentUtils.exportAttachment(decal, selectedFile);
|
||||||
} catch (IOException iex) {
|
} catch (IOException iex) {
|
||||||
|
// FIXME - probably want a simple user dialog here since FileIO is not really a bug.
|
||||||
throw new BugException(iex);
|
throw new BugException(iex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -244,7 +244,7 @@ public class AppearancePanel extends JPanel {
|
|||||||
ab.addChangeListener(new StateChangeListener() {
|
ab.addChangeListener(new StateChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void stateChanged(EventObject e) {
|
public void stateChanged(EventObject e) {
|
||||||
editBtn.setEnabled(ab.getImage() == null);
|
editBtn.setEnabled(ab.getImage() != null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
editBtn.addActionListener(new ActionListener() {
|
editBtn.addActionListener(new ActionListener() {
|
||||||
@ -252,7 +252,7 @@ public class AppearancePanel extends JPanel {
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
try {
|
try {
|
||||||
EditDecalHelper.editDecal(SwingUtilities.getWindowAncestor(AppearancePanel.this), ab.getImage());
|
EditDecalHelper.editDecal(SwingUtilities.getWindowAncestor(AppearancePanel.this), document, c, ab.getImage());
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new BugException(ex);
|
throw new BugException(ex);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,12 +34,14 @@ public class EditDecalDialog extends JDialog {
|
|||||||
private JCheckBox savePref;
|
private JCheckBox savePref;
|
||||||
|
|
||||||
private boolean isCancel = false;
|
private boolean isCancel = false;
|
||||||
|
private boolean editOne = true;
|
||||||
|
|
||||||
public EditDecalDialog(final Window owner) {
|
public EditDecalDialog(final Window owner, boolean promptForEditor, int usageCount) {
|
||||||
super(owner, trans.get("EditDecalDialog.title"), Dialog.ModalityType.APPLICATION_MODAL);
|
super(owner, trans.get("EditDecalDialog.title"), Dialog.ModalityType.APPLICATION_MODAL);
|
||||||
|
|
||||||
JPanel panel = new JPanel(new MigLayout("fill, ins para"));
|
JPanel panel = new JPanel(new MigLayout("fill, ins para"));
|
||||||
|
|
||||||
|
if (promptForEditor) {
|
||||||
JLabel selectLbl = new JLabel(trans.get("EditDecalDialog.lbl.select"));
|
JLabel selectLbl = new JLabel(trans.get("EditDecalDialog.lbl.select"));
|
||||||
panel.add(selectLbl, "gapright, wrap");
|
panel.add(selectLbl, "gapright, wrap");
|
||||||
|
|
||||||
@ -48,7 +50,7 @@ public class EditDecalDialog extends JDialog {
|
|||||||
if (Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) {
|
if (Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) {
|
||||||
|
|
||||||
systemRadio = new JRadioButton(trans.get("EditDecalDialog.lbl.system"));
|
systemRadio = new JRadioButton(trans.get("EditDecalDialog.lbl.system"));
|
||||||
systemRadio.setSelected(false);
|
systemRadio.setSelected(true);
|
||||||
panel.add(systemRadio, "wrap");
|
panel.add(systemRadio, "wrap");
|
||||||
execGroup.add(systemRadio);
|
execGroup.add(systemRadio);
|
||||||
|
|
||||||
@ -113,9 +115,30 @@ public class EditDecalDialog extends JDialog {
|
|||||||
panel.add(chooser, "growx, wrap");
|
panel.add(chooser, "growx, wrap");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usageCount > 1) {
|
||||||
|
ButtonGroup bg = new ButtonGroup();
|
||||||
|
final JRadioButton justThisOne = new JRadioButton("just this one", true);
|
||||||
|
justThisOne.addChangeListener(new ChangeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
EditDecalDialog.this.editOne = justThisOne.isSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
panel.add(justThisOne, "left");
|
||||||
|
bg.add(justThisOne);
|
||||||
|
JRadioButton all = new JRadioButton("all", false);
|
||||||
|
panel.add(all, "gapleft para, right, wrap");
|
||||||
|
bg.add(all);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (promptForEditor) {
|
||||||
savePref = new JCheckBox(trans.get("EditDecalDialog.lbl.always"));
|
savePref = new JCheckBox(trans.get("EditDecalDialog.lbl.always"));
|
||||||
panel.add(savePref, "wrap");
|
panel.add(savePref, "wrap");
|
||||||
|
}
|
||||||
|
|
||||||
// OK / Cancel buttons
|
// OK / Cancel buttons
|
||||||
JButton okButton = new JButton(trans.get("dlg.but.ok"));
|
JButton okButton = new JButton(trans.get("dlg.but.ok"));
|
||||||
@ -142,7 +165,6 @@ public class EditDecalDialog extends JDialog {
|
|||||||
GUIUtil.rememberWindowSize(this);
|
GUIUtil.rememberWindowSize(this);
|
||||||
GUIUtil.setDisposableDialogOptions(this, okButton);
|
GUIUtil.setDisposableDialogOptions(this, okButton);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCancel() {
|
public boolean isCancel() {
|
||||||
@ -161,6 +183,10 @@ public class EditDecalDialog extends JDialog {
|
|||||||
return commandText.getText();
|
return commandText.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEditOne() {
|
||||||
|
return editOne;
|
||||||
|
}
|
||||||
|
|
||||||
public void ok() {
|
public void ok() {
|
||||||
isCancel = false;
|
isCancel = false;
|
||||||
this.setVisible(false);
|
this.setVisible(false);
|
||||||
@ -172,4 +198,3 @@ public class EditDecalDialog extends JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -123,6 +123,10 @@ public class FigureRenderer extends RocketRenderer {
|
|||||||
cr.renderGeometry(gl, c);
|
cr.renderGeometry(gl, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flushTextureCache(GLAutoDrawable drawable) {
|
||||||
|
}
|
||||||
|
|
||||||
private static int getShine(RocketComponent c) {
|
private static int getShine(RocketComponent c) {
|
||||||
if (c instanceof ExternalComponent) {
|
if (c instanceof ExternalComponent) {
|
||||||
switch (((ExternalComponent) c).getFinish()) {
|
switch (((ExternalComponent) c).getFinish()) {
|
||||||
|
|||||||
@ -190,6 +190,13 @@ public class RealisticRenderer extends RocketRenderer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flushTextureCache(GLAutoDrawable drawable) {
|
||||||
|
// Flush the cache twice to get rid of old images.
|
||||||
|
clearCaches(drawable.getGL().getGL2());
|
||||||
|
clearCaches(drawable.getGL().getGL2());
|
||||||
|
}
|
||||||
|
|
||||||
private void clearCaches(GL2 gl) {
|
private void clearCaches(GL2 gl) {
|
||||||
log.debug("ClearCaches");
|
log.debug("ClearCaches");
|
||||||
for (Map.Entry<String, Texture> e : oldTexCache.entrySet()) {
|
for (Map.Entry<String, Texture> e : oldTexCache.entrySet()) {
|
||||||
|
|||||||
@ -107,6 +107,16 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void flushTextureCaches() {
|
||||||
|
canvas.invoke(true, new GLRunnable() {
|
||||||
|
@Override
|
||||||
|
public boolean run(GLAutoDrawable drawable) {
|
||||||
|
rr.flushTextureCache(drawable);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if 3d view is enabled. This may be toggled by the user at
|
* Return true if 3d view is enabled. This may be toggled by the user at
|
||||||
* launch time.
|
* launch time.
|
||||||
|
|||||||
@ -48,6 +48,8 @@ public abstract class RocketRenderer {
|
|||||||
|
|
||||||
public abstract boolean isDrawnTransparent(RocketComponent c);
|
public abstract boolean isDrawnTransparent(RocketComponent c);
|
||||||
|
|
||||||
|
public abstract void flushTextureCache(GLAutoDrawable drawable);
|
||||||
|
|
||||||
public RocketComponent pick(GLAutoDrawable drawable, Configuration configuration, Point p,
|
public RocketComponent pick(GLAutoDrawable drawable, Configuration configuration, Point p,
|
||||||
Set<RocketComponent> ignore) {
|
Set<RocketComponent> ignore) {
|
||||||
final GL2 gl = drawable.getGL().getGL2();
|
final GL2 gl = drawable.getGL().getGL2();
|
||||||
|
|||||||
@ -61,6 +61,7 @@ import net.sf.openrocket.l10n.Translator;
|
|||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
||||||
import net.sf.openrocket.masscalc.MassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||||
|
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
@ -214,6 +215,13 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
@Override
|
@Override
|
||||||
public void stateChanged(EventObject e) {
|
public void stateChanged(EventObject e) {
|
||||||
// System.out.println("Configuration changed, calling updateFigure");
|
// System.out.println("Configuration changed, calling updateFigure");
|
||||||
|
if (is3d) {
|
||||||
|
if (e instanceof ComponentChangeEvent) {
|
||||||
|
if (((ComponentChangeEvent) e).isTextureChange()) {
|
||||||
|
figure3d.flushTextureCaches();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
updateExtras();
|
updateExtras();
|
||||||
updateFigures();
|
updateFigures();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,11 @@ import java.awt.Window;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import net.sf.openrocket.appearance.AppearanceBuilder;
|
||||||
import net.sf.openrocket.appearance.DecalImage;
|
import net.sf.openrocket.appearance.DecalImage;
|
||||||
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
import net.sf.openrocket.gui.dialogs.EditDecalDialog;
|
import net.sf.openrocket.gui.dialogs.EditDecalDialog;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
|
|
||||||
public class EditDecalHelper {
|
public class EditDecalHelper {
|
||||||
@ -18,7 +21,62 @@ public class EditDecalHelper {
|
|||||||
|
|
||||||
private static final SwingPreferences prefs = ((SwingPreferences) Application.getPreferences());
|
private static final SwingPreferences prefs = ((SwingPreferences) Application.getPreferences());
|
||||||
|
|
||||||
public static void editDecal( Window parent, DecalImage decal ) throws IOException {
|
public static void editDecal(Window parent, OpenRocketDocument doc, RocketComponent component, DecalImage decal) throws IOException {
|
||||||
|
|
||||||
|
boolean sysPrefSet = prefs.isDecalEditorPreferenceSet();
|
||||||
|
int usageCount = doc.countDecalUsage(decal);
|
||||||
|
|
||||||
|
//First Check preferences
|
||||||
|
if (sysPrefSet && usageCount == 1) {
|
||||||
|
|
||||||
|
launchEditor(prefs.isDecalEditorPreferenceSystem(), prefs.getDecalEditorCommandLine(), decal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditDecalDialog dialog = new EditDecalDialog(parent, !sysPrefSet, usageCount);
|
||||||
|
dialog.setVisible(true);
|
||||||
|
|
||||||
|
if (dialog.isCancel()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we use the System Preference Editor or from the dialog?
|
||||||
|
boolean useSystemEditor = false;
|
||||||
|
String commandLine = "";
|
||||||
|
|
||||||
|
if (sysPrefSet) {
|
||||||
|
useSystemEditor = prefs.isDecalEditorPreferenceSystem();
|
||||||
|
commandLine = prefs.getDecalEditorCommandLine();
|
||||||
|
} else {
|
||||||
|
useSystemEditor = dialog.isUseSystemEditor();
|
||||||
|
commandLine = dialog.getCommandLine();
|
||||||
|
// Do we need to save the preferences?
|
||||||
|
if (dialog.isSavePreferences()) {
|
||||||
|
prefs.setDecalEditorPreference(useSystemEditor, commandLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialog.isEditOne()) {
|
||||||
|
decal = makeDecalUnique(doc, component, decal);
|
||||||
|
}
|
||||||
|
|
||||||
|
launchEditor(useSystemEditor, commandLine, decal);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DecalImage makeDecalUnique(OpenRocketDocument doc, RocketComponent component, DecalImage decal) {
|
||||||
|
|
||||||
|
DecalImage newImage = doc.makeUniqueDecal(decal);
|
||||||
|
|
||||||
|
AppearanceBuilder appearanceBuilder = new AppearanceBuilder(component.getAppearance());
|
||||||
|
appearanceBuilder.setImage(newImage);
|
||||||
|
|
||||||
|
component.setAppearance(appearanceBuilder.getAppearance());
|
||||||
|
|
||||||
|
return newImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void launchEditor(boolean useSystemEditor, String commandTemplate, DecalImage decal) throws IOException {
|
||||||
|
|
||||||
String decalId = decal.getName();
|
String decalId = decal.getName();
|
||||||
// Create Temp File.
|
// Create Temp File.
|
||||||
@ -31,53 +89,10 @@ public class EditDecalHelper {
|
|||||||
|
|
||||||
decal.exportImage(tmpFile, true);
|
decal.exportImage(tmpFile, true);
|
||||||
|
|
||||||
//First Check preferences
|
|
||||||
if ( prefs.isDecalEditorPreferenceSet() ) {
|
|
||||||
|
|
||||||
// FIXME - need this one or all dialog.
|
|
||||||
|
|
||||||
if ( prefs.isDecalEditorPreferenceSystem() ) {
|
|
||||||
launchSystemEditor( tmpFile );
|
|
||||||
} else {
|
|
||||||
String commandTemplate = prefs.getDecalEditorCommandLine();
|
|
||||||
launchCommandEditor(commandTemplate, tmpFile);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Preference not set, launch dialog
|
|
||||||
EditDecalDialog dialog = new EditDecalDialog(parent);
|
|
||||||
dialog.setVisible(true);
|
|
||||||
|
|
||||||
if( dialog.isCancel() ) {
|
|
||||||
// FIXME - delete tmpfile?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean saveToPrefs = dialog.isSavePreferences();
|
|
||||||
|
|
||||||
if ( dialog.isUseSystemEditor() ) {
|
|
||||||
if ( saveToPrefs ) {
|
|
||||||
prefs.setDecalEditorPreference(true, null);
|
|
||||||
}
|
|
||||||
launchSystemEditor( tmpFile );
|
|
||||||
} else {
|
|
||||||
String commandLine = dialog.getCommandLine();
|
|
||||||
if( saveToPrefs ) {
|
|
||||||
prefs.setDecalEditorPreference(false, commandLine);
|
|
||||||
}
|
|
||||||
launchCommandEditor( commandLine, tmpFile );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void launchSystemEditor( File tmpFile ) throws IOException {
|
|
||||||
|
|
||||||
|
if (useSystemEditor) {
|
||||||
Desktop.getDesktop().edit(tmpFile);
|
Desktop.getDesktop().edit(tmpFile);
|
||||||
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
private static void launchCommandEditor( String commandTemplate, File tmpFile ) throws IOException {
|
|
||||||
|
|
||||||
String filename = tmpFile.getAbsolutePath();
|
String filename = tmpFile.getAbsolutePath();
|
||||||
|
|
||||||
@ -91,5 +106,6 @@ public class EditDecalHelper {
|
|||||||
Runtime.getRuntime().exec(command);
|
Runtime.getRuntime().exec(command);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
37
core/src/net/sf/openrocket/gui/watcher/FileWatcher.java
Normal file
37
core/src/net/sf/openrocket/gui/watcher/FileWatcher.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package net.sf.openrocket.gui.watcher;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public abstract class FileWatcher implements Watchable {
|
||||||
|
|
||||||
|
private final File file;
|
||||||
|
private long lastModifiedTimestamp = 0L;
|
||||||
|
|
||||||
|
public FileWatcher(File file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected File getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WatchEvent monitor() {
|
||||||
|
|
||||||
|
long modified = file.lastModified();
|
||||||
|
if (modified == 0L) {
|
||||||
|
// check for removal?
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (modified > lastModifiedTimestamp) {
|
||||||
|
long oldTimestamp = lastModifiedTimestamp;
|
||||||
|
lastModifiedTimestamp = modified;
|
||||||
|
return (oldTimestamp == 0L) ? null : WatchEvent.MODIFIED;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract void handleEvent(WatchEvent evt);
|
||||||
|
|
||||||
|
}
|
||||||
8
core/src/net/sf/openrocket/gui/watcher/WatchEvent.java
Normal file
8
core/src/net/sf/openrocket/gui/watcher/WatchEvent.java
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package net.sf.openrocket.gui.watcher;
|
||||||
|
|
||||||
|
public enum WatchEvent {
|
||||||
|
|
||||||
|
MODIFIED,
|
||||||
|
REMOVED;
|
||||||
|
|
||||||
|
}
|
||||||
7
core/src/net/sf/openrocket/gui/watcher/WatchKey.java
Normal file
7
core/src/net/sf/openrocket/gui/watcher/WatchKey.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package net.sf.openrocket.gui.watcher;
|
||||||
|
|
||||||
|
public interface WatchKey {
|
||||||
|
|
||||||
|
public void cancel();
|
||||||
|
|
||||||
|
}
|
||||||
7
core/src/net/sf/openrocket/gui/watcher/WatchService.java
Normal file
7
core/src/net/sf/openrocket/gui/watcher/WatchService.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package net.sf.openrocket.gui.watcher;
|
||||||
|
|
||||||
|
public interface WatchService {
|
||||||
|
|
||||||
|
public abstract WatchKey register(Watchable w);
|
||||||
|
|
||||||
|
}
|
||||||
72
core/src/net/sf/openrocket/gui/watcher/WatchServiceImpl.java
Normal file
72
core/src/net/sf/openrocket/gui/watcher/WatchServiceImpl.java
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package net.sf.openrocket.gui.watcher;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class WatchServiceImpl implements WatchService {
|
||||||
|
|
||||||
|
private final static int INTERVAL_MS = 1000;
|
||||||
|
|
||||||
|
private static AtomicInteger threadcount = new AtomicInteger(0);
|
||||||
|
|
||||||
|
private ScheduledExecutorService executor = Executors.newScheduledThreadPool(2, new ThreadFactory() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
Thread t = new Thread(r);
|
||||||
|
t.setName("WatchService-" + threadcount.getAndIncrement());
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public WatchServiceImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see net.sf.openrocket.gui.watcher.WatchService#register(net.sf.openrocket.gui.watcher.Watchable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public WatchKey register(Watchable w) {
|
||||||
|
ScheduledFuture<?> future = executor.scheduleWithFixedDelay(new WatchableRunner(w), 0, INTERVAL_MS, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
return new WatchKeyImpl(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WatchKeyImpl implements WatchKey {
|
||||||
|
|
||||||
|
ScheduledFuture<?> future;
|
||||||
|
|
||||||
|
private WatchKeyImpl(ScheduledFuture<?> future) {
|
||||||
|
this.future = future;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
future.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class WatchableRunner implements Runnable {
|
||||||
|
|
||||||
|
private Watchable w;
|
||||||
|
|
||||||
|
private WatchableRunner(Watchable w) {
|
||||||
|
this.w = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
WatchEvent evt = w.monitor();
|
||||||
|
if (evt != null) {
|
||||||
|
w.handleEvent(evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
9
core/src/net/sf/openrocket/gui/watcher/Watchable.java
Normal file
9
core/src/net/sf/openrocket/gui/watcher/Watchable.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package net.sf.openrocket.gui.watcher;
|
||||||
|
|
||||||
|
public interface Watchable {
|
||||||
|
|
||||||
|
public WatchEvent monitor();
|
||||||
|
|
||||||
|
public void handleEvent(WatchEvent evt);
|
||||||
|
|
||||||
|
}
|
||||||
@ -23,6 +23,8 @@ public class ComponentChangeEvent extends EventObject {
|
|||||||
public static final int MOTOR_CHANGE = 32;
|
public static final int MOTOR_CHANGE = 32;
|
||||||
/** A change that affects the events occurring during flight. */
|
/** A change that affects the events occurring during flight. */
|
||||||
public static final int EVENT_CHANGE = 64;
|
public static final int EVENT_CHANGE = 64;
|
||||||
|
/** A change to the 3D texture assigned to a component*/
|
||||||
|
public static final int TEXTURE_CHANGE = 128;
|
||||||
|
|
||||||
/** A bit-field that contains all possible change types. */
|
/** A bit-field that contains all possible change types. */
|
||||||
public static final int ALL_CHANGE = 0xFFFFFFFF;
|
public static final int ALL_CHANGE = 0xFFFFFFFF;
|
||||||
@ -47,6 +49,9 @@ public class ComponentChangeEvent extends EventObject {
|
|||||||
return (RocketComponent) super.getSource();
|
return (RocketComponent) super.getSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTextureChange() {
|
||||||
|
return (type & TEXTURE_CHANGE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isAerodynamicChange() {
|
public boolean isAerodynamicChange() {
|
||||||
return (type & AERODYNAMIC_CHANGE) != 0;
|
return (type & AERODYNAMIC_CHANGE) != 0;
|
||||||
|
|||||||
@ -2,11 +2,13 @@ package net.sf.openrocket.rocketcomponent;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
|
import java.util.EventObject;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import net.sf.openrocket.appearance.Appearance;
|
import net.sf.openrocket.appearance.Appearance;
|
||||||
|
import net.sf.openrocket.appearance.Decal;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.preset.ComponentPreset;
|
import net.sf.openrocket.preset.ComponentPreset;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
@ -20,6 +22,7 @@ import net.sf.openrocket.util.LineStyle;
|
|||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.SafetyMutex;
|
import net.sf.openrocket.util.SafetyMutex;
|
||||||
import net.sf.openrocket.util.SimpleStack;
|
import net.sf.openrocket.util.SimpleStack;
|
||||||
|
import net.sf.openrocket.util.StateChangeListener;
|
||||||
import net.sf.openrocket.util.UniqueID;
|
import net.sf.openrocket.util.UniqueID;
|
||||||
|
|
||||||
|
|
||||||
@ -423,6 +426,17 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
*/
|
*/
|
||||||
public void setAppearance(Appearance appearance) {
|
public void setAppearance(Appearance appearance) {
|
||||||
this.appearance = appearance;
|
this.appearance = appearance;
|
||||||
|
Decal d = this.appearance.getTexture();
|
||||||
|
if (d != null) {
|
||||||
|
d.getImage().addChangeListener(new StateChangeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateChanged(EventObject e) {
|
||||||
|
fireComponentChangeEvent(ComponentChangeEvent.TEXTURE_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package net.sf.openrocket.startup;
|
|||||||
import net.sf.openrocket.database.ComponentPresetDao;
|
import net.sf.openrocket.database.ComponentPresetDao;
|
||||||
import net.sf.openrocket.database.motor.MotorDatabase;
|
import net.sf.openrocket.database.motor.MotorDatabase;
|
||||||
import net.sf.openrocket.database.motor.ThrustCurveMotorSetDatabase;
|
import net.sf.openrocket.database.motor.ThrustCurveMotorSetDatabase;
|
||||||
|
import net.sf.openrocket.gui.watcher.WatchService;
|
||||||
import net.sf.openrocket.l10n.ClassBasedTranslator;
|
import net.sf.openrocket.l10n.ClassBasedTranslator;
|
||||||
import net.sf.openrocket.l10n.DebugTranslator;
|
import net.sf.openrocket.l10n.DebugTranslator;
|
||||||
import net.sf.openrocket.l10n.ExceptionSuppressingTranslator;
|
import net.sf.openrocket.l10n.ExceptionSuppressingTranslator;
|
||||||
@ -68,7 +69,9 @@ public final class Application {
|
|||||||
Application.logger = logger;
|
Application.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static WatchService getWatchService() {
|
||||||
|
return Application.injector.getInstance(WatchService.class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the log buffer.
|
* Return the log buffer.
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
package net.sf.openrocket.startup;
|
package net.sf.openrocket.startup;
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
import net.sf.openrocket.gui.watcher.WatchService;
|
||||||
|
import net.sf.openrocket.gui.watcher.WatchServiceImpl;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.logging.LogHelper;
|
import net.sf.openrocket.logging.LogHelper;
|
||||||
import net.sf.openrocket.util.watcher.DirectoryChangeReactor;
|
import net.sf.openrocket.util.watcher.DirectoryChangeReactor;
|
||||||
import net.sf.openrocket.util.watcher.DirectoryChangeReactorImpl;
|
import net.sf.openrocket.util.watcher.DirectoryChangeReactorImpl;
|
||||||
|
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
|
||||||
public class ApplicationModule extends AbstractModule {
|
public class ApplicationModule extends AbstractModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -15,6 +17,7 @@ public class ApplicationModule extends AbstractModule {
|
|||||||
bind(Preferences.class).toInstance(Application.getPreferences());
|
bind(Preferences.class).toInstance(Application.getPreferences());
|
||||||
bind(Translator.class).toInstance(Application.getTranslator());
|
bind(Translator.class).toInstance(Application.getTranslator());
|
||||||
bind(DirectoryChangeReactor.class).to(DirectoryChangeReactorImpl.class);
|
bind(DirectoryChangeReactor.class).to(DirectoryChangeReactorImpl.class);
|
||||||
|
bind(WatchService.class).to(WatchServiceImpl.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user