Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.josue.tileset.editor; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import static com.josue.tileset.editor.Tile.TILE_SIZE; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Transparency; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.Timer; import javax.swing.border.LineBorder; import javax.swing.filechooser.FileNameExtensionFilter; /** * * @author Josue */ public class Editor extends javax.swing.JFrame { /** * Creates new form NewApplication */ JFrame frame; public Editor() { 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() { jFileChooser1 = new javax.swing.JFileChooser(); jFileChooser2 = new javax.swing.JFileChooser(); jDialog1 = new javax.swing.JDialog(); jDialog2 = new javax.swing.JDialog(); jDialog3 = new javax.swing.JDialog(); buttonGroup1 = new javax.swing.ButtonGroup(); jPanel1 = new javax.swing.JPanel(); previewLabel = new javax.swing.JLabel(); animatedTb = new javax.swing.JCheckBox(); lightTb = new javax.swing.JCheckBox(); solidTb = new javax.swing.JCheckBox(); jPanel2 = new javax.swing.JPanel(); jSpinner1 = new javax.swing.JSpinner(); jLabel1 = new javax.swing.JLabel(); jPanel3 = new javax.swing.JPanel(); animatedAction = new javax.swing.JRadioButton(); lightsourceAction = new javax.swing.JRadioButton(); jLabel2 = new javax.swing.JLabel(); jButton1 = new javax.swing.JButton(); exportBtn = new javax.swing.JButton(); imagePanel = new javax.swing.JPanel(); javax.swing.GroupLayout jDialog1Layout = new javax.swing.GroupLayout(jDialog1.getContentPane()); jDialog1.getContentPane().setLayout(jDialog1Layout); jDialog1Layout.setHorizontalGroup(jDialog1Layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, Short.MAX_VALUE)); jDialog1Layout.setVerticalGroup(jDialog1Layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 300, Short.MAX_VALUE)); javax.swing.GroupLayout jDialog2Layout = new javax.swing.GroupLayout(jDialog2.getContentPane()); jDialog2.getContentPane().setLayout(jDialog2Layout); jDialog2Layout.setHorizontalGroup(jDialog2Layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, Short.MAX_VALUE)); jDialog2Layout.setVerticalGroup(jDialog2Layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 300, Short.MAX_VALUE)); javax.swing.GroupLayout jDialog3Layout = new javax.swing.GroupLayout(jDialog3.getContentPane()); jDialog3.getContentPane().setLayout(jDialog3Layout); jDialog3Layout.setHorizontalGroup(jDialog3Layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, Short.MAX_VALUE)); jDialog3Layout.setVerticalGroup(jDialog3Layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 300, Short.MAX_VALUE)); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setPreferredSize(new java.awt.Dimension(600, 700)); jPanel1.setBackground(new java.awt.Color(102, 102, 102)); jPanel1.setForeground(new java.awt.Color(255, 255, 255)); previewLabel.setBackground(new java.awt.Color(0, 0, 0)); previewLabel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); previewLabel.setMaximumSize(new java.awt.Dimension(32, 32)); previewLabel.setMinimumSize(new java.awt.Dimension(32, 32)); previewLabel.setPreferredSize(new java.awt.Dimension(32, 32)); animatedTb.setText("Animated"); animatedTb.setEnabled(false); animatedTb.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { animatedTbActionPerformed(evt); } }); lightTb.setText("Light Source"); lightTb.setEnabled(false); lightTb.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { lightTbActionPerformed(evt); } }); solidTb.setText("Solid"); solidTb.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { solidTbActionPerformed(evt); } }); jPanel2.setBackground(new java.awt.Color(153, 153, 255)); jSpinner1.setModel(new javax.swing.SpinnerNumberModel(Long.valueOf(1000L), Long.valueOf(100L), Long.valueOf(60000L), Long.valueOf(100L))); jSpinner1.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { jSpinner1StateChanged(evt); } }); jLabel1.setText("Interval"); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout .setHorizontalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup().addGap(14, 14, 14).addComponent(jLabel1) .addGap(18, 18, 18) .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, 51, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(109, Short.MAX_VALUE))); jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup().addGap(23, 23, 23) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel1)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))); buttonGroup1.add(animatedAction); animatedAction.setSelected(true); animatedAction.setText("Animated"); buttonGroup1.add(lightsourceAction); lightsourceAction.setText("Light Source"); lightsourceAction.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { lightsourceActionActionPerformed(evt); } }); jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel2.setText("Right button"); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup(jPanel3Layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup().addGroup(jPanel3Layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup().addContainerGap() .addComponent(lightsourceAction)) .addGroup(jPanel3Layout.createSequentialGroup().addGap(19, 19, 19).addComponent(jLabel2)) .addGroup(jPanel3Layout.createSequentialGroup().addContainerGap() .addComponent(animatedAction))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))); jPanel3Layout.setVerticalGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup().addGap(9, 9, 9).addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(animatedAction) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(lightsourceAction).addContainerGap(32, Short.MAX_VALUE))); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup(jPanel1Layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(solidTb, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(animatedTb, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lightTb, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) .addGroup(jPanel1Layout.createSequentialGroup().addGap(91, 91, 91) .addComponent(previewLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))); jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup().addContainerGap() .addComponent(previewLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18).addComponent(solidTb) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(animatedTb) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(lightTb) .addGap(18, 18, 18) .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap())); jButton1.setText("Load"); jButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); } }); exportBtn.setText("Export"); exportBtn.setEnabled(false); exportBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { exportBtnActionPerformed(evt); } }); imagePanel.setBackground(new java.awt.Color(0, 0, 0)); imagePanel.setPreferredSize(new java.awt.Dimension(350, 448)); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup().addGroup(layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup().addContainerGap().addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup().addGap(10, 10, 10).addComponent(jButton1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(exportBtn))) .addGap(29, 29, 29) .addComponent(imagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 381, Short.MAX_VALUE) .addContainerGap())); layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup( javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup().addGap(11, 11, 11) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton1).addComponent(exportBtn)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(imagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap())); pack(); }// </editor-fold>//GEN-END:initComponents private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed JFileChooser fileDialog = new JFileChooser(); fileDialog.setFileFilter(new FileNameExtensionFilter("Image file", "png")); fileDialog.showOpenDialog(null); inputFile = fileDialog.getSelectedFile(); if (inputFile != null) { loadFile(inputFile); } }//GEN-LAST:event_jButton1ActionPerformed private void lightTbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_lightTbActionPerformed }//GEN-LAST:event_lightTbActionPerformed private void solidTbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_solidTbActionPerformed selectedTile.setSolid(!selectedTile.isSolid()); }//GEN-LAST:event_solidTbActionPerformed private void animatedTbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_animatedTbActionPerformed if (selectedTile.isAnimated()) { // selectAnimatedSequence(); } }//GEN-LAST:event_animatedTbActionPerformed private void jSpinner1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSpinner1StateChanged long value = (long) jSpinner1.getValue(); selectedTile.getAnimation().setAnimationInterval(value); animatedPerformer.stop(); //restart the performer animatedPerformer = new Timer((int) (selectedTile.getAnimation().getAnimationInterval()), new TileAnimator(selectedTile, previewLabel, loadedTiles)); animatedPerformer.start(); }//GEN-LAST:event_jSpinner1StateChanged private void lightsourceActionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_lightsourceActionActionPerformed // TODO add your handling code here: }//GEN-LAST:event_lightsourceActionActionPerformed private void exportBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportBtnActionPerformed JFileChooser fileDialog = new JFileChooser(); fileDialog.setFileFilter(new FileNameExtensionFilter("Json file", "json")); String outputFileName = inputFile.getAbsolutePath().split("\\.")[0] + ".json"; fileDialog.setSelectedFile(new File(outputFileName)); if (fileDialog.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { File file = fileDialog.getSelectedFile(); ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE); mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); try { mapper.writeValue(file, loadedTiles); } catch (IOException ex) { Logger.getLogger(Editor.class.getName()).log(Level.SEVERE, null, ex); } } }//GEN-LAST:event_exportBtnActionPerformed /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(Editor.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(Editor.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(Editor.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(Editor.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new Editor().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton animatedAction; private javax.swing.JCheckBox animatedTb; private javax.swing.ButtonGroup buttonGroup1; private javax.swing.JButton exportBtn; private javax.swing.JPanel imagePanel; private javax.swing.JButton jButton1; private javax.swing.JDialog jDialog1; private javax.swing.JDialog jDialog2; private javax.swing.JDialog jDialog3; private javax.swing.JFileChooser jFileChooser1; private javax.swing.JFileChooser jFileChooser2; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JSpinner jSpinner1; private javax.swing.JCheckBox lightTb; private javax.swing.JRadioButton lightsourceAction; private javax.swing.JLabel previewLabel; private javax.swing.JCheckBox solidTb; // End of variables declaration//GEN-END:variables private File inputFile; private Tile selectedTile; Map<Tile, JLabel> tileLabels = new LinkedHashMap<>(); List<Tile> loadedTiles = new LinkedList<>(); private Timer animatedPerformer; private int offsetDirection = 1; //1 or -1 private int offset = 0; private void loadFile(File file) { this.revalidate(); try { BufferedImage tilesetImage = ImageIO.read(file); if (tilesetImage.getWidth() % TILE_SIZE != 0 || tilesetImage.getHeight() % TILE_SIZE != 0) { JOptionPane.showMessageDialog(this, "Image size not compatible with 32px per Tile"); return; } loadedTiles = loadTile(tilesetImage, file); mountButtons(loadedTiles, tilesetImage.getWidth() / TILE_SIZE, tilesetImage.getHeight() / TILE_SIZE); exportBtn.setEnabled(true); } catch (IOException ex) { Logger.getLogger(Editor.class.getName()).log(Level.SEVERE, null, ex); } } private List<Tile> loadTile(BufferedImage bi, File file) throws IOException { String propFileName = file.getParent() + File.separator + file.getName().split("\\.")[0] + ".json"; File tilePropFile = new File(propFileName); List<Tile> loadedTiles = new LinkedList<>(); if (tilePropFile.exists()) { ObjectMapper objectMapper = new ObjectMapper(); loadedTiles = objectMapper.readValue(tilePropFile, new TypeReference<LinkedList<Tile>>() { }); } List<Tile> tiles = new LinkedList<>(); int tileId = 1; for (int y = 0; y < bi.getHeight() / TILE_SIZE; y++) { for (int x = 0; x < bi.getWidth() / TILE_SIZE; x++) { Tile tile; if (loadedTiles.isEmpty()) { tile = new Tile(); tile.setId(tileId); tile.setSolid(false); } else { tile = loadedTiles.get(tileId - 1); } tile.setImage(getTileImage(x, y, bi)); tiles.add(tile); tileId++; } } return tiles; } private BufferedImage getTileImage(int x, int y, BufferedImage tileSetImage) { BufferedImage tileImage; Graphics2D tileGraphics; float opacity = 1L; tileImage = createTileImage(); tileGraphics = tileImage.createGraphics(); tileGraphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity)); tileGraphics.drawImage(tileSetImage, 0, // destiny x1 0, // destiny y1 TILE_SIZE, // destiny x2 TILE_SIZE, // destiny y2 x * TILE_SIZE, // source x1 y * TILE_SIZE, // source y1 x * TILE_SIZE + TILE_SIZE, // source x2 y * TILE_SIZE + TILE_SIZE, // source y2 null); return tileImage; } private BufferedImage createTileImage() { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gs = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gs.getDefaultConfiguration(); BufferedImage tileImage = gc.createCompatibleImage(TILE_SIZE, TILE_SIZE, Transparency.TRANSLUCENT); // return new BufferedImage(Tile.TILE_SIZE, Tile.TILE_SIZE, BufferedImage.TYPE_INT_ARGB); return tileImage; } private void mountButtons(List<Tile> tiles, int cols, int rows) { imagePanel.removeAll(); if (animatedPerformer != null) { animatedPerformer.stop(); animatedPerformer = null; } imagePanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); Dimension dimension = new Dimension(cols * TILE_SIZE, rows * TILE_SIZE); for (Tile tile : tiles) { final JLabel tileLabel = new JLabel(); tileLabel.setIcon(new ImageIcon(tile.getImage())); Dimension labelDimension = new Dimension(TILE_SIZE, TILE_SIZE); tileLabel.setMinimumSize(labelDimension); tileLabel.setMaximumSize(labelDimension); tileLabel.setPreferredSize(labelDimension); tileLabel.setSize(labelDimension); tileLabel.addMouseListener(new java.awt.event.MouseAdapter() { @Override public void mouseClicked(java.awt.event.MouseEvent evt) { if (SwingUtilities.isRightMouseButton(evt)) {//select animated sequence if (animatedAction.isSelected()) { addAnimatedTile(tile); } else { addLightSourceTile(tile); } } else { if (animatedPerformer != null) { animatedPerformer.stop(); } Iterator<JLabel> iterator = tileLabels.values().iterator(); while (iterator.hasNext()) { JLabel next = iterator.next(); next.revalidate(); } imagePanel.repaint(); for (Map.Entry<Tile, JLabel> entry : tileLabels.entrySet()) { Tile key = entry.getKey(); JLabel value = entry.getValue(); value.setBorder(null); //clear borders } selectedTile = tile;//this isolate for the next operations tileLabel.setBorder(new LineBorder(Color.RED, 2)); previewLabel.setIcon(new ImageIcon(tile.getImage())); animatedTb.setSelected(selectedTile.isAnimated()); lightTb.setSelected(selectedTile.isLight()); solidTb.setSelected(selectedTile.isSolid()); if (tile.isAnimated()) { for (Integer animatesTileOffset : selectedTile.getAnimation().getAnimatedSequence()) { //display animated borders for (Map.Entry<Tile, JLabel> entry : tileLabels.entrySet()) { Tile key = entry.getKey(); JLabel value = entry.getValue(); if (key.getId() == selectedTile.getId() + animatesTileOffset) { value.setBorder(new LineBorder(Color.BLUE, 2)); } } } animatedPerformer = new Timer( (int) (selectedTile.getAnimation().getAnimationInterval()), new TileAnimator(selectedTile, previewLabel, loadedTiles)); animatedPerformer.start(); } if (selectedTile.isLight()) {//light color has preference for (Tile tile : tiles) { if (tile.getId() == selectedTile.getLightTileId()) { JLabel found = tileLabels.get(tile); found.setBorder(new LineBorder(Color.YELLOW, 2)); break; } } } } } @Override public void mouseExited(MouseEvent e) { if (selectedTile != null && selectedTile.getAnimation() != null && selectedTile.getAnimation() .getAnimatedSequence().contains(tile.getId() - selectedTile.getId())) { tileLabel.setBorder(new LineBorder(Color.BLUE, 2)); } else if (selectedTile != null && selectedTile.isLight() && selectedTile.getLightTileId() == tile.getId()) { tileLabel.setBorder(new LineBorder(Color.YELLOW, 2)); } else if (selectedTile != null) { JLabel get = tileLabels.get(selectedTile); if (!get.equals(tileLabel)) { //keep the red border if is the selected tileLabel.setBorder(null); } } else { tileLabel.setBorder(null); } } @Override public void mouseEntered(MouseEvent e) { if (selectedTile != null && selectedTile.getAnimation() != null && !selectedTile.getAnimation().getAnimatedSequence() .contains(tile.getId() - selectedTile.getId()) && tile.getLight() != null && tile.getLight().getLightTileOffset() != 0) { tileLabel.setBorder(new LineBorder(Color.RED, 2)); } else if (selectedTile == null) { tileLabel.setBorder(new LineBorder(Color.RED, 2)); } } }); tileLabels.put(tile, tileLabel); imagePanel.add(tileLabel); } imagePanel.setMaximumSize(dimension); imagePanel.setMinimumSize(dimension); imagePanel.setPreferredSize(dimension); imagePanel.revalidate(); imagePanel.repaint(); this.pack(); } enum RIGH_CLICK_ACTION { ANIMATED, LIGHT_SOURCE } private void addAnimatedTile(Tile tile) { if (!tile.equals(selectedTile) && selectedTile != null) { //cannot add the same tile as sequence JLabel label = tileLabels.get(tile); int animatedTileOffset = tile.getId() - selectedTile.getId(); if (selectedTile.getAnimation() != null && selectedTile.getAnimation().getAnimatedSequence().contains(animatedTileOffset)) { selectedTile.getAnimation().getAnimatedSequence() .remove(selectedTile.getAnimation().getAnimatedSequence().indexOf(animatedTileOffset)); if (selectedTile.getAnimation().getAnimatedSequence().isEmpty()) { //is not an animated tile anymore label.setBorder(null); selectedTile.setAnimation(null); } if (animatedPerformer != null) { animatedPerformer.stop(); } } else {//new animated tile if (animatedPerformer != null) { animatedPerformer.stop(); } if (!selectedTile.isAnimated()) { selectedTile.setAnimation(new Animation()); } selectedTile.getAnimation().getAnimatedSequence().add(animatedTileOffset); label.setBorder(new LineBorder(Color.BLUE, 2)); animatedTb.setSelected(true); animatedPerformer = new Timer((int) (selectedTile.getAnimation().getAnimationInterval()), new TileAnimator(selectedTile, previewLabel, loadedTiles)); animatedPerformer.start(); } } } private void addLightSourceTile(Tile tile) { if (!tile.equals(selectedTile) && selectedTile != null) { JLabel label = tileLabels.get(tile); if (tile.getId() == selectedTile.getId()) { //already contains selectedTile.setLight(null); label.setBorder(null); } else { selectedTile.setLight(new Light()); selectedTile.getLight().setLightTileOffset(tile.getId() - selectedTile.getId()); label.setBorder(new LineBorder(Color.YELLOW, 2)); lightTb.setSelected(true); } } } }