public Tool createTool(Class<? extends Tool> toolClass) { Tool tool; try { Constructor<? extends Tool> constructor = toolClass.getDeclaredConstructor(new Class[] {}); tool = constructor.newInstance(new Object[] {}); // tool = constructor.newInstance((Object) null); buttonGroup.add(tool); toolMap.put(toolClass, tool); tool.setToolbox(this); return tool; } catch (InstantiationException e) { TabletopTool.showError( I18N.getText("msg.error.toolCannotInstantiate", toolClass.getName()), e); } catch (IllegalAccessException e) { TabletopTool.showError( I18N.getText("msg.error.toolNeedPublicConstructor", toolClass.getName()), e); } catch (NoSuchMethodException nsme) { TabletopTool.showError( I18N.getText("msg.error.toolNeedValidConstructor", toolClass.getName()), nsme); } catch (InvocationTargetException ite) { TabletopTool.showError( I18N.getText("msg.error.toolConstructorFailed", toolClass.getName()), ite); } return null; }
private void exportButtonAction() { // This block is to allow preservation of existing dialog behavior: // Neither button is set when the dialog first appears, so we have to // make sure the user picks one. Presumably this is to force the user // to pay attention to this choice and not just accept a default. if (!(ExportRadioButtons.VIEW_GM.isChecked() || ExportRadioButtons.VIEW_PLAYER.isChecked())) { TabletopTool.showError(I18N.getString("dialog.screenshot.error.mustSelectView"), null); return; } // LOCATION // TODO: Show a progress dialog // TODO: Make this less fragile switch (formPanel.getTabbedPane("tabs").getSelectedIndex()) { case 0: File file = new File(formPanel.getText("locationTextField")); // PNG only supported for now if (!file.getName().toLowerCase().endsWith(".png")) { file = new File(file.getAbsolutePath() + ".png"); } exportLocation = new LocalLocation(file); break; case 1: String username = formPanel.getText("username"); String password = formPanel.getText("password"); String host = formPanel.getText("host"); String path = formPanel.getText("path"); // PNG only supported for now if (!path.toLowerCase().endsWith(".png")) { path += ".png"; } exportLocation = new FTPLocation(username, password, host, path); break; } try { screenCapture(); } catch (Exception ex) { TabletopTool.showError(I18N.getString("dialog.screenshot.error.failedExportingImage"), ex); } finally { dispose(); } }
private void updateSightTypeCombo() { List<String> typeList = new ArrayList<String>(TabletopTool.getCampaign().getSightTypes()); Collections.sort(typeList); DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>(typeList.toArray(new String[typeList.size()])); getSightTypeCombo().setModel(model); }
private List<com.t3.model.campaign.TokenProperty> getPropertyList() { if (propertyList == null) { propertyList = TabletopTool.getCampaign() .getTokenPropertyList((String) getPropertyTypeCombo().getSelectedItem()); } return propertyList; }
public ExportDialogOld() { super(TabletopTool.getFrame(), "Export Screenshot", true); // The window uses about 1MB. Disposing frees this, but repeated uses // will cause more memory fragmentation. // MCL: I figure it's better to save the 1MB for low-mem systems, // but it would be even better to HIDE it, and then dispose() it // when the user clicks on the memory meter to free memory // setDefaultCloseOperation(HIDE_ON_CLOSE); setDefaultCloseOperation(DISPOSE_ON_CLOSE); // // Initialize the panel and button actions // formPanel = new FormPanel("com/t3/client/ui/forms/exportDialog.xml"); setLayout(new GridLayout()); add(formPanel); getRootPane().setDefaultButton((JButton) formPanel.getButton("exportButton")); pack(); ExportRadioButtons.setForm(formPanel); ExportLayers.setForm(formPanel); formPanel .getButton("exportButton") .addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { exportButtonAction(); } }); formPanel .getButton("cancelButton") .addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { dispose(); } }); formPanel .getButton("browseButton") .addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { browseButtonAction(); } }); // Run this once to make sure the dialog is in a good starting state. ExportLayers.setDefaultChecked(); enforceButtonRules(); }
@Override public void setVisible(boolean b) { // In case something changed while the dialog was closed... enforceButtonRules(); if (b) { SwingUtil.centerOver(this, TabletopTool.getFrame()); } super.setVisible(b); }
/** Sets the layer-selection checkboxes to replicate the "current view". */ public void setToDefault() { final Zone zone = TabletopTool.getFrame().getCurrentZoneRenderer().getZone(); if (this == ExportLayers.LAYER_FOG) { ExportLayers.LAYER_FOG.setChecked(zone.hasFog()); } else if (this == ExportLayers.LAYER_VISIBILITY) { ExportLayers.LAYER_VISIBILITY.setChecked(zone.getVisionType() != Zone.VisionType.OFF); } else { setChecked(true); } }
/** * This is a wrapper that preserves the layer settings on the Zone object. It calls {@link * takeEntireMapScreenShot()} to to the real work. * * @return the image to be saved to a file */ private static BufferedImage entireMapScreenShotWithLayers() throws Exception, OutOfMemoryError { final Zone zone = TabletopTool.getFrame().getCurrentZoneRenderer().getZone(); // // Preserve settings // // psuedo-layers final Zone.VisionType savedVision = zone.getVisionType(); final boolean savedFog = zone.hasFog(); final boolean savedBoard = zone.drawBoard(); // real layers final boolean savedToken = Zone.Layer.TOKEN.isEnabled(); final boolean savedHidden = Zone.Layer.GM.isEnabled(); final boolean savedObject = Zone.Layer.OBJECT.isEnabled(); final boolean savedBackground = Zone.Layer.BACKGROUND.isEnabled(); // // set according to dialog options // zone.setHasFog(ExportLayers.LAYER_FOG.isChecked()); if (!ExportLayers.LAYER_VISIBILITY.isChecked()) zone.setVisionType(Zone.VisionType.OFF); zone.setDrawBoard(ExportLayers.LAYER_BOARD.isChecked()); Zone.Layer.TOKEN.setEnabled(ExportLayers.LAYER_TOKEN.isChecked()); Zone.Layer.GM.setEnabled(ExportLayers.LAYER_HIDDEN.isChecked()); Zone.Layer.OBJECT.setEnabled(ExportLayers.LAYER_OBJECT.isChecked()); Zone.Layer.BACKGROUND.setEnabled(ExportLayers.LAYER_BACKGROUND.isChecked()); // This 'cache invalidation' is handled by setZone inside takeEntireMapScreenShot() // but it should be more robust. // TabletopTool.getFrame().getCurrentZoneRenderer().invalidateCurrentViewCache(); // // screenshot! // MCL: NOTE: while turning off Fog, there is a possibility the players // may see the map flash for a second with fog turned off-- need to look into // whether this is true. BufferedImage image = null; try { image = takeEntireMapScreenShot(); } finally { // // Restore settings // zone.setHasFog(savedFog); zone.setVisionType(savedVision); zone.setDrawBoard(savedBoard); Zone.Layer.TOKEN.setEnabled(savedToken); Zone.Layer.GM.setEnabled(savedHidden); Zone.Layer.OBJECT.setEnabled(savedObject); Zone.Layer.BACKGROUND.setEnabled(savedBackground); // TabletopTool.getFrame().getCurrentZoneRenderer().invalidateCurrentViewCache(); } return image; }
public static void setDefaultChecked() { // everything defaults to 'on' since the layers don't really have on/off capability // outside of this screenshot code for (ExportLayers layer : ExportLayers.values()) { layer.setChecked(true); } // however, some psuedo-layers do have a state, so set that appropriately final Zone zone = TabletopTool.getFrame().getCurrentZoneRenderer().getZone(); ExportLayers.LAYER_VISIBILITY.setChecked(zone.getVisionType() != Zone.VisionType.OFF); ExportLayers.LAYER_FOG.setChecked(zone.hasFog()); }
public void setSizeCombo(Token token) { JComboBox size = getSizeCombo(); Grid grid = TabletopTool.getFrame().getCurrentZoneRenderer().getZone().getGrid(); DefaultComboBoxModel model = new DefaultComboBoxModel(grid.getFootprints().toArray()); model.insertElementAt(token.getLayer() == Layer.TOKEN ? "Native Size" : "Free Size", 0); size.setModel(model); if (token.isSnapToScale()) { size.setSelectedItem(token.getFootprint(grid)); } else { size.setSelectedIndex(0); } }
/** * Stores the form this is attached to, so we don't have to store duplicate data locally (like * selected and enabled). Also perform some error checking, since we _are_ duplicating the * description of the form itself (like what buttons it has). * * @param form The FormPanel this dialog is part of. */ public static void setForm(FormPanel form) { ExportLayers.form = form; for (ExportLayers button : ExportLayers.values()) { try { if (form.getButton(button.toString()) == null) { throw new Exception("Export Dialog has a mis-matched enum: " + button.toString()); } } catch (Exception ex) { TabletopTool.showError( I18N.getString("dialog.screenshot.layer.button.uiImplementationError"), ex); } } }
/** * Ensures that the user can only check/uncheck boxes as appropriate. For example, if "fog" is not * enabled on the map, it cannot be enabled for export. * * <p>This should get called during initialization and whenever the radio buttons change. * * <p>The GM and Players have different rules, to prevent players from gaining knowledge they * should not have using the screenshot (such as revealing things under other things by disabling * layers). Players can basically only turn off tokens, to get an 'empty' version of the map. */ public static void enforceButtonRules() { if (!TabletopTool.getPlayer().isGM()) { ExportRadioButtons.VIEW_PLAYER.setChecked(true); ExportRadioButtons.VIEW_PLAYER.setEnabled(true); ExportRadioButtons.VIEW_GM.setEnabled(false); } if (ExportRadioButtons.LAYERS_CURRENT.isChecked()) { // By "current layers" we mean what you see in the editor, which is everything. // So disable mucking about with layers. formPanel.getLabel("LAYERS_LABEL").setEnabled(false); ExportLayers.setDefaultChecked(); ExportLayers.setDisabled(); } else /* if (ExportRadioButtons.LAYERS_AS_SELECTED.isChecked()) */ { formPanel.getLabel("LAYERS_LABEL").setEnabled(true); boolean isGM = ExportRadioButtons.VIEW_GM.isChecked(); final Zone zone = TabletopTool.getFrame().getCurrentZoneRenderer().getZone(); for (ExportLayers layer : ExportLayers.values()) { boolean enabled = isGM || layer.playerCanModify; // Regardless of whether it is a player or GM, // only enable fog and visibility check-boxes // when the map has those things turned on. switch (layer) { case LAYER_VISIBILITY: enabled &= (zone.getVisionType() != Zone.VisionType.OFF); break; case LAYER_FOG: enabled &= zone.hasFog(); break; } layer.setEnabled(enabled); if (!enabled) { layer.setToDefault(); } } } }
private void updatePropertyTypeCombo() { List<String> typeList = new ArrayList<String>(TabletopTool.getCampaign().getTokenTypes()); Collections.sort(typeList); DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>(typeList.toArray(new String[typeList.size()])); getPropertyTypeCombo().setModel(model); getPropertyTypeCombo() .addItemListener( new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { updatePropertiesTable((String) getPropertyTypeCombo().getSelectedItem()); } }); }
public void showDialog(Token token) { dialog = new GenericDialog( I18N.getString("EditTokenDialog.msg.title"), TabletopTool.getFrame(), this) { private static final long serialVersionUID = 5439449816096482201L; @Override public void closeDialog() { // TODO: I don't like this. There should really be a AbeilleDialog class that does this unbind(); super.closeDialog(); } }; bind(token); getRootPane().setDefaultButton(getOKButton()); dialog.showDialog(); }
/** * This is the top-level screen-capture routine. It sends the resulting PNG image to the location * previously selected by the user. TODO: It currently calls {@link * TabletopTool.takeMapScreenShot()} for "normal" screenshots, but that's just until this code is * considered stable enough. * * @throws Exception */ public void screenCapture() throws Exception { BufferedImage screenCap = null; TabletopTool.getFrame() .setStatusMessage(I18N.getString("dialog.screenshot.msg.GeneratingScreenshot")); ExportRadioButtons type = ExportRadioButtons.getType(); try { switch (type) { case TYPE_CURRENT_VIEW: // This uses the original screenshot code: I didn't want to touch it, so I need // to pass it the same parameter it took before. Player.Role role = ExportRadioButtons.VIEW_GM.isChecked() ? Player.Role.GM : Player.Role.PLAYER; screenCap = TabletopTool.takeMapScreenShot(new PlayerView(role)); // since old screenshot code doesn't throw exceptions, look for null if (screenCap == null) { throw new Exception(I18N.getString("dialog.screenshot.error.failedImageGeneration")); } break; case TYPE_ENTIRE_MAP: screenCap = entireMapScreenShotWithLayers(); break; default: throw new Exception(I18N.getString("dialog.screenshot.error.invalidDialogSettings")); } TabletopTool.getFrame() .setStatusMessage(I18N.getString("dialog.screenshot.msg.screenshotStreaming")); try (ByteArrayOutputStream imageOut = new ByteArrayOutputStream()) { ImageIO.write(screenCap, "png", imageOut); screenCap = null; // Free up the memory as soon as possible TabletopTool.getFrame() .setStatusMessage(I18N.getString("dialog.screenshot.msg.screenshotSaving")); exportLocation.putContent( new BufferedInputStream(new ByteArrayInputStream(imageOut.toByteArray()))); } TabletopTool.getFrame() .setStatusMessage(I18N.getString("dialog.screenshot.msg.screenshotSaved")); } catch (OutOfMemoryError e) { TabletopTool.showError("Out Of Memory", e); } catch (Exception ex) { TabletopTool.showError("screenCapture()", ex); } }
public OwnerListModel() { List<String> list = new ArrayList<String>(); Set<String> ownerSet = getModel().getOwners(); list.addAll(ownerSet); ObservableList<Player> playerList = TabletopTool.getPlayerList(); for (Object item : playerList) { Player player = (Player) item; String playerId = player.getName(); if (!list.contains(playerId)) { list.add(playerId); } } Collections.sort(list); for (String id : list) { Selectable selectable = new DefaultSelectable(id); selectable.setSelected(ownerSet.contains(id)); ownerList.add(selectable); } }
// // SetForm stores the form this is attached to // public static void setForm(FormPanel form) { ExportRadioButtons.form = form; for (ExportRadioButtons button : ExportRadioButtons.values()) { try { if (form.getRadioButton(button.toString()) == null) { throw new Exception("Export Dialog has a mis-matched enum: " + button.toString()); } button.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { enforceButtonRules(); } }); } catch (Exception ex) { TabletopTool.showError( I18N.getString("dialog.screenshot.radio.button.uiImplementationError"), ex); } } }
public void initGMNotesTextArea() { getGMNotesTextArea().addMouseListener(new MouseHandler(getGMNotesTextArea())); getComponent("@GMNotes").setEnabled(TabletopTool.getPlayer().isGM()); }
private void updateStatesPanel() { // Group the states first into individual panels List<BooleanTokenOverlay> overlays = new ArrayList<BooleanTokenOverlay>(TabletopTool.getCampaign().getTokenStatesMap().values()); Map<String, JPanel> groups = new TreeMap<String, JPanel>(); groups.put("", new JPanel(new FormLayout("0px:grow 2px 0px:grow 2px 0px:grow 2px 0px:grow"))); for (BooleanTokenOverlay overlay : overlays) { String group = overlay.getGroup(); if (group != null && (group = group.trim()).length() != 0) { JPanel panel = groups.get(group); if (panel == null) { panel = new JPanel(new FormLayout("0px:grow 2px 0px:grow 2px 0px:grow 2px 0px:grow")); panel.setBorder(BorderFactory.createTitledBorder(group)); groups.put(group, panel); } } } // Add the group panels and bar panel to the states panel JPanel panel = getStatesPanel(); panel.removeAll(); FormLayout layout = new FormLayout("0px:grow"); panel.setLayout(layout); int row = 1; for (JPanel gPanel : groups.values()) { layout.appendRow(new RowSpec("pref")); layout.appendRow(new RowSpec("2px")); panel.add(gPanel, new CellConstraints(1, row)); row += 2; } layout.appendRow(new RowSpec("pref")); layout.appendRow(new RowSpec("2px")); JPanel barPanel = new JPanel(new FormLayout("right:pref 2px pref 5px right:pref 2px pref")); panel.add(barPanel, new CellConstraints(1, row)); // Add the individual check boxes. for (BooleanTokenOverlay state : overlays) { String group = state.getGroup(); panel = groups.get(""); if (group != null && (group = group.trim()).length() != 0) panel = groups.get(group); int x = panel.getComponentCount() % 4; int y = panel.getComponentCount() / 4; if (x == 0) { layout = (FormLayout) panel.getLayout(); if (y != 0) layout.appendRow(new RowSpec("2px")); layout.appendRow(new RowSpec("pref")); } panel.add(new JCheckBox(state.getName()), new CellConstraints(x * 2 + 1, y * 2 + 1)); } // Add sliders to the bar panel if (TabletopTool.getCampaign().getTokenBarsMap().size() > 0) { layout = (FormLayout) barPanel.getLayout(); barPanel.setName("bar"); barPanel.setBorder(BorderFactory.createTitledBorder("Bars")); int count = 0; row = 0; for (BarTokenOverlay bar : TabletopTool.getCampaign().getTokenBarsMap().values()) { int working = count % 2; if (working == 0) { // slider row layout.appendRow(new RowSpec("pref")); row += 1; } JPanel labelPanel = new JPanel(new FormLayout("pref", "pref 2px:grow pref")); barPanel.add(labelPanel, new CellConstraints(1 + working * 4, row)); labelPanel.add( new JLabel(bar.getName() + ":"), new CellConstraints(1, 1, CellConstraints.RIGHT, CellConstraints.TOP)); JSlider slider = new JSlider(0, 100); JCheckBox hide = new JCheckBox("Hide"); hide.putClientProperty("JSlider", slider); hide.addChangeListener( new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { JSlider js = (JSlider) ((JCheckBox) e.getSource()).getClientProperty("JSlider"); js.setEnabled(!((JCheckBox) e.getSource()).isSelected()); } }); labelPanel.add(hide, new CellConstraints(1, 3, CellConstraints.RIGHT, CellConstraints.TOP)); slider.setName(bar.getName()); slider.setPaintLabels(true); slider.setPaintTicks(true); slider.setMajorTickSpacing(20); slider.createStandardLabels(20); slider.setMajorTickSpacing(10); barPanel.add(slider, new CellConstraints(3 + working * 4, row)); if (working != 0) { // spacer row layout.appendRow(new RowSpec("2px")); row += 1; } count += 1; } } }
@Override public boolean commit() { Token token = getModel(); if (getNameField().getText().equals("")) { TabletopTool.showError("msg.error.emptyTokenName"); return false; } if (getSpeechTable().isEditing()) { getSpeechTable().getCellEditor().stopCellEditing(); } if (getPropertyTable().isEditing()) { getPropertyTable().getCellEditor().stopCellEditing(); } // Commit the changes to the token properties if (!super.commit()) { return false; } // SIZE token.setSnapToScale(getSizeCombo().getSelectedIndex() != 0); if (getSizeCombo().getSelectedIndex() > 0) { Grid grid = TabletopTool.getFrame().getCurrentZoneRenderer().getZone().getGrid(); token.setFootprint(grid, (TokenFootprint) getSizeCombo().getSelectedItem()); } // Other token.setPropertyType((String) getPropertyTypeCombo().getSelectedItem()); token.setSightType((String) getSightTypeCombo().getSelectedItem()); // Get the states Component[] stateComponents = getStatesPanel().getComponents(); Component barPanel = null; for (int j = 0; j < stateComponents.length; j++) { if ("bar".equals(stateComponents[j].getName())) { barPanel = stateComponents[j]; continue; } Component[] components = ((Container) stateComponents[j]).getComponents(); for (int i = 0; i < components.length; i++) { JCheckBox cb = (JCheckBox) components[i]; String state = cb.getText(); token.setState(state, cb.isSelected()); } } // endfor // BARS if (barPanel != null) { Component[] bars = ((Container) barPanel).getComponents(); for (int i = 0; i < bars.length; i += 2) { JCheckBox cb = (JCheckBox) ((Container) bars[i]).getComponent(1); JSlider bar = (JSlider) bars[i + 1]; Float value = cb.isSelected() ? null : new Float(bar.getValue() / 100f); token.setBar(bar.getName(), value); } } // Ownership // If the token is owned by all and we are a player don't alter the ownership list. if (TabletopTool.getPlayer().isGM() || !token.isOwnedByAll()) { token.clearAllOwners(); for (int i = 0; i < getOwnerList().getModel().getSize(); i++) { DefaultSelectable selectable = (DefaultSelectable) getOwnerList().getModel().getElementAt(i); if (selectable.isSelected()) { token.addOwner((String) selectable.getObject()); } } // If we are not a GM and the only non GM owner make sure we can't // take our selves off of the owners list if (!TabletopTool.getPlayer().isGM()) { boolean hasPlayer = false; Set<String> owners = token.getOwners(); if (owners != null) { Iterator<Player> playerIter = TabletopTool.getPlayerList().iterator(); while (playerIter.hasNext()) { Player pl = playerIter.next(); if (!pl.isGM() && owners.contains(pl.getName())) { hasPlayer = true; } } } if (!hasPlayer) { token.addOwner(TabletopTool.getPlayer().getName()); } } } // SHAPE token.setShape((Token.TokenShape) getShapeCombo().getSelectedItem()); // Macros token.setSpeechMap(((KeyValueTableModel) getSpeechTable().getModel()).getMap()); // Properties ((TokenPropertyTableModel) getPropertyTable().getModel()).applyTo(token); // Charsheet if (getCharSheetPanel().getImageId() != null) { T3Util.uploadAsset(AssetManager.getAsset(getCharSheetPanel().getImageId())); } token.setCharsheetImage(getCharSheetPanel().getImageId()); // IMAGE if (!token.getImageAssetId().equals(getTokenIconPanel().getImageId())) { BufferedImage image = ImageManager.getImageAndWait(getTokenIconPanel().getImageId()); T3Util.uploadAsset(AssetManager.getAsset(getTokenIconPanel().getImageId())); token.setImageAsset(null, getTokenIconPanel().getImageId()); // Default image for now token.setWidth(image.getWidth(null)); token.setHeight(image.getHeight(null)); } // PORTRAIT if (getPortraitPanel().getImageId() != null) { // Make sure the server has the image if (!TabletopTool.getCampaign().containsAsset(getPortraitPanel().getImageId())) { TabletopTool.serverCommand() .putAsset(AssetManager.getAsset(getPortraitPanel().getImageId())); } } token.setPortraitImage(getPortraitPanel().getImageId()); // LAYOUT token.setSizeScale(getTokenLayoutPanel().getSizeScale()); token.setAnchor(getTokenLayoutPanel().getAnchorX(), getTokenLayoutPanel().getAnchorY()); // OTHER tokenSaved = true; // Character Sheet // Map<String, Object> properties = controller.getData(); // for (String prop : token.getPropertyNames()) // token.setProperty(prop, properties.get(prop)); // Update UI TabletopTool.getFrame().updateTokenTree(); TabletopTool.getFrame().resetTokenPanels(); return true; }
/** * Finds the extents of the map, then takes a 'screenshot' of that area. If the user is the GM, * the extents include every object and everything that has any area, such as 'fog' and * 'visibility' objects. * * <p>If a background tiling texture is used, the image is aligned to it, so that it can be used * on re-import as a new base map image. * * <p>If the user is a player (or GM posing as a player), the extents only go as far as the * revealed fog-of-war. * * @return the image to be saved */ private static BufferedImage takeEntireMapScreenShot() throws Exception, OutOfMemoryError { final ZoneRenderer renderer = TabletopTool.getFrame().getCurrentZoneRenderer(); if (renderer == null) { throw (new Exception("renderer = NULL")); } boolean viewAsPlayer = ExportRadioButtons.VIEW_PLAYER.isChecked(); // // First, figure out the 'extents' of the canvas // This will be later modified by the fog (for players), // and by the tiling texture (for re-importing) // final PlayerView view = new PlayerView(viewAsPlayer ? Player.Role.PLAYER : Player.Role.GM); Rectangle extents = renderer.zoneExtents(view); try { // Clip to what the players know about (if applicable). // This keeps the player from exporting the map to learn which // direction has more 'stuff' in it. if (viewAsPlayer) { Rectangle fogE = renderer.fogExtents(); // TabletopTool.showError(fogE.x + " " + fogE.y + " " + fogE.width + " " + fogE.height); if ((fogE.width < 0) || (fogE.height < 0)) { TabletopTool.showError( I18N.getString( "dialog.screenshot.error.negativeFogExtents")); // Image is not clipped to show // only fog-revealed areas!")); } else { extents = extents.intersection(fogE); } } } catch (Exception ex) { throw (new Exception(I18N.getString("dialog.screenshot.error.noArea"), ex)); } if ((extents == null) || (extents.width == 0) || (extents.height == 0)) { throw (new Exception(I18N.getString("dialog.screenshot.error.noArea"))); } // If output includes the tiling 'board' texture, move the upper-left corner // to an integer multiple of the background tile (so it matches up on import). // We don't need to move the lower-right corner because it doesn't matter for // aligning on importing. boolean drawBoard = ExportLayers.LAYER_BOARD.isChecked(); if (drawBoard) { DrawablePaint paint = renderer.getZone().getBackgroundPaint(); DrawableTexturePaint dummy = new DrawableTexturePaint(); Integer tileX = 0, tileY = 0; if (paint.getClass() == dummy.getClass()) { Image bgTexture = ImageManager.getImage(((DrawableTexturePaint) paint).getAsset().getId()); tileX = bgTexture.getWidth(null); tileY = bgTexture.getHeight(null); Integer x = ((int) Math.floor((float) extents.x / tileX)) * tileX; Integer y = ((int) Math.floor((float) extents.y / tileY)) * tileY; extents.width = extents.width + (extents.x - x); extents.height = extents.height + (extents.y - y); extents.x = x; extents.y = y; } } // Save the original state of the renderer to restore later. // Create a place to put the image, and // set up the renderer to encompass the whole extents of the map. Rectangle origBounds = renderer.getBounds(); Scale origScale = renderer.getZoneScale(); Dimension origSize = renderer.getSize(); BufferedImage image = null; try { image = new BufferedImage(extents.width, extents.height, Transparency.OPAQUE); } catch (OutOfMemoryError me) { throw new OutOfMemoryError("image size = " + extents.width + " x " + extents.height); } catch (Exception e) { throw new Exception("image size = " + extents.width + " x " + extents.height, e); } final Graphics2D g = image.createGraphics(); g.setClip(0, 0, extents.width, extents.height); Scale s = new Scale(); s.setOffset(-extents.x, -extents.y); // Finally, draw the image. // Copied this thread concept from the original screenshot code in TabletopTool. // Have to do this on the EDT so that there aren't any odd side effects // of rendering using a renderer that's on screen. try { renderer.setZoneScale(s); renderer.setBounds(extents); renderer.setSize(extents.getSize()); if (!EventQueue.isDispatchThread()) { EventQueue.invokeAndWait( new Runnable() { @Override public void run() { renderer.renderZone(g, view); } }); } else { renderer.renderZone(g, view); } return image; } catch (OutOfMemoryError me) { throw new OutOfMemoryError("image size = " + extents.width + " x " + extents.height); } catch (InterruptedException ie) { TabletopTool.showError("While creating snapshot", ie); } catch (InvocationTargetException ite) { TabletopTool.showError("While creating snapshot", ite); } catch (Exception e) { throw new Exception("image size = " + extents.width + " x " + extents.height, e); } finally { g.dispose(); // Restore original state renderer.setBounds(origBounds); renderer.setZoneScale(origScale); renderer.setSize(origSize); } // This is just to avoid the compiler error: it should be unreachable return null; }
@Override public void bind(final Token token) { // ICON getTokenIconPanel().setImageId(token.getImageAssetId()); // PROPERTIES updatePropertyTypeCombo(); updatePropertiesTable(token.getPropertyType()); // SIGHT updateSightTypeCombo(); // STATES Component barPanel = null; updateStatesPanel(); Component[] statePanels = getStatesPanel().getComponents(); for (int j = 0; j < statePanels.length; j++) { if ("bar".equals(statePanels[j].getName())) { barPanel = statePanels[j]; continue; } Component[] states = ((Container) statePanels[j]).getComponents(); for (int i = 0; i < states.length; i++) { JCheckBox state = (JCheckBox) states[i]; state.setSelected(token.hasState(state.getText())); } } // BARS if (barPanel != null) { Component[] bars = ((Container) barPanel).getComponents(); for (int i = 0; i < bars.length; i += 2) { JCheckBox cb = (JCheckBox) ((Container) bars[i]).getComponent(1); JSlider bar = (JSlider) bars[i + 1]; if (token.getBar(bar.getName()) == null) { cb.setSelected(true); bar.setEnabled(false); bar.setValue(100); } else { cb.setSelected(false); bar.setEnabled(true); bar.setValue((int) (token.getBar(bar.getName()) * 100)); } } } // OWNER LIST EventQueue.invokeLater( new Runnable() { @Override public void run() { getOwnerList().setModel(new OwnerListModel()); } }); // SPEECH TABLE EventQueue.invokeLater( new Runnable() { @Override public void run() { getSpeechTable().setModel(new SpeechTableModel(token)); } }); // Player player = TabletopTool.getPlayer(); // boolean editable = player.isGM() || // !TabletopTool.getServerPolicy().useStrictTokenManagement() || // token.isOwner(player.getName()); // getAllPlayersCheckBox().setSelected(token.isOwnedByAll()); // OTHER getShapeCombo().setSelectedItem(token.getShape()); setSizeCombo(token); getPropertyTypeCombo().setSelectedItem(token.getPropertyType()); getSightTypeCombo() .setSelectedItem( token.getSightType() != null ? token.getSightType() : TabletopTool.getCampaign().getCampaignProperties().getDefaultSightType()); getCharSheetPanel().setImageId(token.getCharsheetImage()); getPortraitPanel().setImageId(token.getPortraitImage()); getTokenLayoutPanel().setToken(token); // we will disable the Owner only visible check box if the token is not // visible to players to signify the relationship ActionListener tokenVisibleActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { AbstractButton abstractButton = (AbstractButton) actionEvent.getSource(); boolean selected = abstractButton.getModel().isSelected(); getVisibleOnlyToOwnerCheckBox().setEnabled(selected); getVisibleOnlyToOwnerLabel().setEnabled(selected); } }; getVisibleCheckBox().addActionListener(tokenVisibleActionListener); // Character Sheets // controller = null; // String form = TabletopTool.getCampaign().getCharacterSheets().get(token.getPropertyType()); // if (form == null) // return; // URL formUrl = getClass().getClassLoader().getResource(form); // if (formUrl == null) // return; // controller = new CharSheetController(formUrl, null); // HashMap<String, Object> properties = new HashMap<String, Object>(); // for (String prop : token.getPropertyNames()) // properties.put(prop, token.getProperty(prop)); // controller.setData(properties); // controller.getPanel().setName("characterSheet"); // replaceComponent("sheetPanel", "characterSheet", controller.getPanel()); super.bind(token); }