Package se.llbit.chunky.ui

Source Code of se.llbit.chunky.ui.Controls

/* Copyright (c) 2010-2013 Jesper Öqvist <jesper@llbit.se>
*
* This file is part of Chunky.
*
* Chunky is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chunky is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Chunky.  If not, see <http://www.gnu.org/licenses/>.
*/
package se.llbit.chunky.ui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.NumberFormat;
import java.util.Hashtable;

import javax.swing.ButtonGroup;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.apache.log4j.Logger;

import se.llbit.chunky.PersistentSettings;
import se.llbit.chunky.launcher.LauncherSettings;
import se.llbit.chunky.main.BlockTypeListCellRenderer;
import se.llbit.chunky.main.Chunky;
import se.llbit.chunky.main.Messages;
import se.llbit.chunky.renderer.ui.SceneDirectoryPicker;
import se.llbit.chunky.resources.MinecraftFinder;
import se.llbit.chunky.resources.MiscImages;
import se.llbit.chunky.resources.Texture;
import se.llbit.chunky.resources.TexturePackLoader;
import se.llbit.chunky.resources.TexturePackLoader.TextureLoadingError;
import se.llbit.chunky.world.Block;
import se.llbit.chunky.world.Chunk;
import se.llbit.chunky.world.Icon;
import se.llbit.chunky.world.World;

/**
* This is the toolbox that's shown in the left part of the main Chunky GUI.
*
* It has a tabbed pane which currently contains three tabs; View, Edit, Highlight
*
* @author Jesper Öqvist (jesper@llbit.se)
*/
@SuppressWarnings("serial")
public class Controls extends JPanel {

  private static final Logger logger =
      Logger.getLogger(Controls.class);

  private static final int WIDTH_BIG = 300;

  private static final int RENDER_TAB_INDEX = 4;

  private final Chunky chunky;
  private JTextField scaleField;
  private JSlider scaleSlider;
  private JTextField layerField;
  private JSlider layerSlider;
  private JButton deleteChunksBtn;
  private final ImageIcon faceIcon;
  private final JButton clearSelectionBtn1 = new JButton();
  private final JButton clearSelectionBtn2 = new JButton();
  private ProgressPanel progressPanel;
  private final Minimap minimap;
  private JButton exportZipBtn;
  private JRadioButton overworldBtn;
  private JRadioButton netherBtn;
  private JRadioButton endBtn;
  private final JCheckBox followPlayer = new JCheckBox("follow player");

  private WorldSelector worldSelector = null;

  private JTextField xField;

  private JTextField zField;

  private JTabbedPane tabbedPane;

  /**
   * @param chunky
   * @param minimap
   */
  public Controls(Chunky chunky, Minimap minimap) {
    this.chunky = chunky;
    this.minimap = minimap;

    faceIcon = new ImageIcon(MiscImages.face);

    initComponents();
  }

  /**
   * Set up the Swing GUI.
   */
  private void initComponents() {
    setMinimumSize(new Dimension(257, 500));

    tabbedPane = new JTabbedPane();

    addTab("Map View", Icon.map.imageIcon(), buildViewPanel(), "Change map view");
    addTab("Chunks", Icon.mapSelected.imageIcon(), buildEditPanel(), "Chunk operations");
    addTab("Highlight", Icon.redTorchOn.imageIcon(), buildHighlightPanel(), "Change block highlight settings");
    addTab("Options", Icon.wrench.imageIcon(), buildOptionsPanel(), "Configure Chunky");
    addTab("3D Render", Icon.sky.imageIcon(), buildRenderPanel(), "Render chunks in 3D");
    addTab("About", Texture.unknown.imageIcon(), buildAboutPanel(), "About Chunky");

    JButton selectWorldBtn = new JButton();
    selectWorldBtn.setText(Messages.getString("Controls.SelectWorld_lbl")); //$NON-NLS-1$
    selectWorldBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        openWorldSelector();
      }
    });

    JButton reloadWorldBtn = new JButton("Reload");
    reloadWorldBtn.setIcon(Icon.reload.imageIcon());
    reloadWorldBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        chunky.reloadWorld();
      }
    });

    GroupLayout layout = new GroupLayout(this);
    setLayout(layout);
    layout.setHorizontalGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addGroup(layout.createParallelGroup(Alignment.LEADING)
        .addComponent(minimap, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
        .addGroup(layout.createSequentialGroup()
            .addComponent(selectWorldBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG/2, Short.MAX_VALUE)
            .addComponent(reloadWorldBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG/2, Short.MAX_VALUE))
        .addComponent(tabbedPane, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
      )
      .addContainerGap()
    );
    layout.setVerticalGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addComponent(minimap, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
      .addGroup(layout.createParallelGroup()
        .addComponent(selectWorldBtn, GroupLayout.PREFERRED_SIZE, 33, 33)
        .addComponent(reloadWorldBtn, GroupLayout.PREFERRED_SIZE, 33, 33)
      )
      .addPreferredGap(ComponentPlacement.RELATED)
      .addComponent(tabbedPane, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
      .addContainerGap()
    );
  }

  /**
   * Add a tab and ensure that the icon is to the left of the text in the
   * tab label.
   *
   * @param title
   * @param icon
   * @param component
   * @param tip
   */
  private void addTab(String title, ImageIcon icon, Component component, String tip) {
    int index = tabbedPane.getTabCount();

    tabbedPane.add(component);

    JLabel lbl = new JLabel(title, icon, SwingConstants.RIGHT);
    lbl.setIconTextGap(5);

    tabbedPane.setTabComponentAt(index, lbl);
    tabbedPane.setToolTipTextAt(index, tip);
  }

  /**
   * Build the highlight tab.
   * This is where the user selects which block type to highlight
   * and the color of the highlight.
   * @return the highlight tab component
   */
  private JComponent buildHighlightPanel() {

    JLabel highlightLbl = new JLabel(
        "<html>Highlights blocks of the selected type.<br>" +
        "Only blocks in the current layer are highlighted!");

    JComponent highlightPanel = new JPanel();

    JButton colorChooserBtn = new JButton();

    colorChooserBtn.setText("Change Color");
    colorChooserBtn.setToolTipText("Change the highlight color");
    colorChooserBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        Color color = JColorChooser.showDialog(chunky.getFrame(),
            "Choose Highlight Color", chunky.getHighlightColor());
        if (color != null)
          chunky.setHighlightColor(color);
      }
    });

    JCheckBox enableHighlight = new JCheckBox();
    enableHighlight.setText("Enable Highlight");
    enableHighlight.setSelected(chunky.isHighlightEnabled());
    enableHighlight.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        JCheckBox s = (JCheckBox) e.getSource();
        chunky.setHighlightEnable(s.isSelected());
      }
    });

    Block[] highlightBlocks = new Block[] {
        Block.DIRT,
        Block.GRASS,
        Block.STONE,
        Block.COBBLESTONE,
        Block.MOSSSTONE,
        Block.IRONORE,
        Block.COALORE,
        Block.REDSTONEORE,
        Block.DIAMONDORE,
        Block.GOLDORE,
        Block.MONSTERSPAWNER,
        Block.BRICKS,
        Block.CLAY,
        Block.LAPISLAZULIORE,
        Block.EMERALDORE,
        Block.NETHERQUARTZORE
      };
    JComboBox blockTypeBox = new JComboBox(highlightBlocks);// BLAWK TYPE BAWKS
    blockTypeBox.setSelectedItem(chunky.getHighlightBlock());
    blockTypeBox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        JComboBox btb = (JComboBox) e.getSource();
        chunky.highlightBlock((Block) btb.getSelectedItem());
      }
    });
    blockTypeBox.setRenderer(new BlockTypeListCellRenderer());

    GroupLayout layout = new GroupLayout(highlightPanel);
    highlightPanel.setLayout(layout);
    layout.setHorizontalGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addGroup(layout.createParallelGroup(Alignment.LEADING)
        .addComponent(highlightLbl)
        .addComponent(enableHighlight, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
        .addComponent(blockTypeBox, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
        .addComponent(colorChooserBtn))
      .addContainerGap()
    );
    layout.setVerticalGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addComponent(highlightLbl)
      .addPreferredGap(ComponentPlacement.UNRELATED)
      .addComponent(enableHighlight, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
      .addComponent(blockTypeBox, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
      .addPreferredGap(ComponentPlacement.RELATED)
      .addComponent(colorChooserBtn)
      .addContainerGap(10, 10)
    );

    return highlightPanel;
  }

  private JComponent buildOptionsPanel() {

    JComponent optionsPanel = new JPanel();

    JButton loadTexturePackBtn = new JButton("Load Resource Pack");
    loadTexturePackBtn.setIcon(Icon.load.imageIcon());
    loadTexturePackBtn.setToolTipText("Load a custom resource pack");
    loadTexturePackBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        CenteredFileDialog fileDialog =
            new CenteredFileDialog(chunky.getFrame(),
                "Load Resource Pack", FileDialog.LOAD);
        fileDialog.setDirectory(MinecraftFinder
            .getResourcePacksDirectory().getAbsolutePath());
        fileDialog.setFilenameFilter(
            new FilenameFilter() {
              @Override
              public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".zip");
              }
            });
        fileDialog.setVisible(true);
        File selectedFile = fileDialog.getSelectedFile();
        if (selectedFile != null) {
          try {
            TexturePackLoader.loadTexturePack(selectedFile, true);
            chunky.reloadWorld();
          } catch (TextureLoadingError e1) {
            System.err.println("Error: failed to load default texture pack!");
          }
        }
      }
    });

    JButton loadDefaultTexturesBtn = new JButton("Load Default Textures");
    loadDefaultTexturesBtn.setToolTipText("Attempt to load the default Minecraft textures");
    loadDefaultTexturesBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        try {
          TexturePackLoader.loadTexturePack(MinecraftFinder.getMinecraftJar(), true);
          chunky.reloadWorld();
        } catch (TextureLoadingError e1) {
          System.err.println("Error: failed to load default texture pack!");
        }
      }
    });

    JCheckBox showLauncher = new JCheckBox("Show launcher when starting Chunky");
    LauncherSettings settings = new LauncherSettings();
    settings.load();
    showLauncher.setSelected(settings.showLauncher);
    showLauncher.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        JCheckBox source = (JCheckBox) e.getSource();
        LauncherSettings settings = new LauncherSettings();
        settings.load();
        settings.showLauncher = source.isSelected();
        settings.save();
      }
    });

    GroupLayout layout = new GroupLayout(optionsPanel);
    optionsPanel.setLayout(layout);
    layout.setHorizontalGroup(layout.createParallelGroup()
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup()
          .addComponent(loadTexturePackBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
          .addComponent(loadDefaultTexturesBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
          .addComponent(showLauncher)
        )
        .addContainerGap()
      )
    );
    layout.setVerticalGroup(layout.createParallelGroup()
    .addGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addComponent(loadTexturePackBtn)
      .addPreferredGap(ComponentPlacement.RELATED)
      .addComponent(loadDefaultTexturesBtn)
      .addPreferredGap(ComponentPlacement.UNRELATED)
      .addComponent(showLauncher)
      .addContainerGap())
    );

    return optionsPanel;
  }

  private JComponent buildRenderPanel() {

    JComponent renderPanel = new JPanel();

    JButton newSceneBtn = new JButton();
    newSceneBtn.setText("New Scene");
    newSceneBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        chunky.open3DView();
      }
    });

    JButton testCLBtn = new JButton("Test OpenCL");
    testCLBtn.setVisible(chunky.options.openCLEnabled);
    testCLBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        chunky.openCLTestRenderer();
      }
    });

    JButton benchmarkBtn = new JButton("Benchmark Renderer");
    benchmarkBtn.setToolTipText("Benchmark the renderer.");
    benchmarkBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        chunky.runBenchmark();
      }
    });

    JButton loadSceneBtn = new JButton("Load Scene");
    loadSceneBtn.setIcon(Icon.load.imageIcon());
    loadSceneBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        chunky.loadScene();
      }
    });

    JSeparator sep1 = new JSeparator();
    JSeparator sep2 = new JSeparator();

    clearSelectionBtn1.setText(Messages.getString("Controls.ClearSelected_lbl")); //$NON-NLS-1$
    clearSelectionBtn1.setEnabled(false);
    clearSelectionBtn1.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.clearSelectedChunks();
      }
    });

    JButton openSceneDirBtn = new JButton("Open Scene Directory");
    openSceneDirBtn.setVisible(Desktop.isDesktopSupported());
    openSceneDirBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        try {
          if (Desktop.isDesktopSupported()) {
            File sceneDir = SceneDirectoryPicker.getCurrentSceneDirectory();
            if (sceneDir != null) {
              Desktop.getDesktop().open(sceneDir);
            }
          }
        } catch (IOException e) {
          logger.warn("Failed to open scene directory", e);
        }
      }
    });

    JButton changeSceneDirBtn = new JButton("Change Scene Directory");
    changeSceneDirBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        SceneDirectoryPicker.changeSceneDirectory(chunky.getFrame());
      }
    });

    GroupLayout layout = new GroupLayout(renderPanel);
    renderPanel.setLayout(layout);
    layout.setHorizontalGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addGroup(layout.createParallelGroup()
        .addComponent(clearSelectionBtn1)
        .addComponent(sep1)
        .addComponent(newSceneBtn)
        .addComponent(loadSceneBtn)
        .addComponent(sep2)
        .addComponent(testCLBtn)
        .addComponent(benchmarkBtn)
        .addComponent(openSceneDirBtn)
        .addComponent(changeSceneDirBtn)
      )
      .addContainerGap()
    );
    layout.setVerticalGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addComponent(clearSelectionBtn1)
      .addPreferredGap(ComponentPlacement.UNRELATED)
      .addComponent(sep1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
      .addPreferredGap(ComponentPlacement.UNRELATED)
      .addComponent(newSceneBtn)
      .addPreferredGap(ComponentPlacement.UNRELATED)
      .addComponent(loadSceneBtn)
      .addPreferredGap(ComponentPlacement.UNRELATED)
      .addComponent(sep2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
      .addPreferredGap(ComponentPlacement.UNRELATED)
      .addComponent(testCLBtn)
      .addPreferredGap(ComponentPlacement.UNRELATED)
      .addComponent(benchmarkBtn)
      .addPreferredGap(ComponentPlacement.UNRELATED)
      .addComponent(openSceneDirBtn)
      .addPreferredGap(ComponentPlacement.RELATED)
      .addComponent(changeSceneDirBtn)
      .addContainerGap()
    );

    return renderPanel;
  }

  private JComponent buildAboutPanel() {

    JComponent aboutPanel = new JPanel();

    JLabel aboutLbl = new JLabel();
    aboutLbl.setText(Messages.getString("Controls.AboutText")); //$NON-NLS-1$

    JButton visitWikiBtn = new JButton("Visit the Wiki");
    visitWikiBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        if (Desktop.isDesktopSupported()) {
          try {
            Desktop.getDesktop().browse(new URI("http://chunky.llbit.se"));
          } catch (IOException e1) {
            e1.printStackTrace();
          } catch (URISyntaxException e1) {
            e1.printStackTrace();
          }
        }
      }
    });

    JButton visitDevBlogBtn = new JButton("Visit Online Community");
    visitDevBlogBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        if (Desktop.isDesktopSupported()) {
          try {
            Desktop.getDesktop().browse(new URI("http://www.reddit.com/r/chunky"));
          } catch (IOException e1) {
            e1.printStackTrace();
          } catch (URISyntaxException e1) {
            e1.printStackTrace();
          }
        }
      }
    });

    JButton showCreditsBtn = new JButton("View Credits");
    showCreditsBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        Credits credits = new Credits(chunky.getFrame());
        credits.setVisible(true);
      }
    });

    GroupLayout layout = new GroupLayout(aboutPanel);
    aboutPanel.setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
          .addContainerGap()
          .addGroup(layout.createParallelGroup(Alignment.LEADING)
            .addComponent(aboutLbl, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
            .addComponent(visitWikiBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
            .addComponent(visitDevBlogBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
            .addComponent(showCreditsBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE))
          .addContainerGap())
      );
    layout.setVerticalGroup(
      layout.createParallelGroup(Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(aboutLbl, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(ComponentPlacement.UNRELATED)
        .addComponent(visitWikiBtn, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(ComponentPlacement.UNRELATED)
        .addComponent(visitDevBlogBtn, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(ComponentPlacement.UNRELATED)
        .addComponent(showCreditsBtn, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
        .addContainerGap())
    );

    return aboutPanel;
  }

  /**
   * Build the view tab.
   * @return the view tab component
   */
  private JComponent buildViewPanel() {

    JComponent viewPanel = new JPanel();

    ButtonGroup mapModeGroup = new ButtonGroup();
    JLabel viewLabel = new JLabel();
    JRadioButton autoModeBtn = new JRadioButton();
    JRadioButton layerModeBtn = new JRadioButton();
    JRadioButton surfaceModeBtn = new JRadioButton();
    JRadioButton caveModeBtn = new JRadioButton();
    JRadioButton biomeModeBtn = new JRadioButton();
    JSeparator sep1 = new JSeparator();
    JLabel scaleLabel = new JLabel();
    scaleField = new JFormattedTextField(NumberFormat.getInstance());
    scaleSlider = new ImprovedSlider(Chunky.BLOCK_SCALE_MIN, Chunky.BLOCK_SCALE_MAX);
    scaleSlider.setValue(chunky.getScale());
    JLabel layerLabel = new JLabel();
    layerField = new JFormattedTextField(NumberFormat.getInstance());
    layerSlider = new ImprovedSlider(0, Chunk.Y_MAX);
    JLabel dimLabel = new JLabel();
    followPlayer.setSelected(PersistentSettings.getFollowPlayer());
    followPlayer.addActionListener(followPlayerListener);

    ButtonGroup buttonGroup2 = new ButtonGroup();
    overworldBtn = new JRadioButton();
    netherBtn = new JRadioButton();
    endBtn = new JRadioButton();

    dimLabel.setText(Messages.getString("Controls.Dimension_lbl")); //$NON-NLS-1$

    buttonGroup2.add(overworldBtn);
    overworldBtn.setText(Messages.getString("Controls.Earth_lbl")); //$NON-NLS-1$
    overworldBtn.setSelected(true);
    overworldBtn.setEnabled(false);
    overworldBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.setDimension(World.OVERWORLD_DIMENSION);
      }
    });

    buttonGroup2.add(netherBtn);
    netherBtn.setText(Messages.getString("Controls.Nether_lbl")); //$NON-NLS-1$
    netherBtn.setEnabled(false);
    netherBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.setDimension(World.NETHER_DIMENSION);
      }
    });

    buttonGroup2.add(endBtn);
    endBtn.setText(Messages.getString("Controls.End_lbl")); //$NON-NLS-1$
    endBtn.setEnabled(false);
    endBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.setDimension(World.END_DIMENSION);
      }
    });

    viewLabel.setText(Messages.getString("Controls.ViewMode_lbl")); //$NON-NLS-1$

    autoModeBtn.setText("Auto");
    autoModeBtn.setSelected(true);
    autoModeBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.setRenderer(Chunk.autoRenderer);
      }
    });
    mapModeGroup.add(autoModeBtn);

    layerModeBtn.setText(Messages.getString("Controls.LayerMode_lbl")); //$NON-NLS-1$
    layerModeBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.setRenderer(Chunk.layerRenderer);
      }
    });
    mapModeGroup.add(layerModeBtn);

    surfaceModeBtn.setText(Messages.getString("Controls.SurfaceMode_lbl")); //$NON-NLS-1$
    surfaceModeBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.setRenderer(Chunk.surfaceRenderer);
      }
    });
    mapModeGroup.add(surfaceModeBtn);

    caveModeBtn.setText(Messages.getString("Controls.CaveMode_lbl")); //$NON-NLS-1$
    caveModeBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.setRenderer(Chunk.caveRenderer);
      }
    });
    mapModeGroup.add(caveModeBtn);

    biomeModeBtn.setText("Biomes");
    biomeModeBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.setRenderer(Chunk.biomeRenderer);
      }
    });
    mapModeGroup.add(biomeModeBtn);

    scaleLabel.setText(Messages.getString("Controls.Scale_lbl")); //$NON-NLS-1$

    setScale(chunky.getScale());
    scaleField.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        String text = scaleField.getText();
        try {
          chunky.setScale(Integer.parseInt(text));
        } catch (NumberFormatException e1) {
        }
      }
    });

    scaleSlider.addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent e) {
        JSlider source = (JSlider) e.getSource();
        chunky.setScale(source.getValue());
      }
    });

    layerLabel.setText(Messages.getString("Controls.Layer_lbl")); //$NON-NLS-1$

    layerField.setText(""+chunky.getLayer());
    layerField.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        String text = layerField.getText();
        chunky.setLayer(Integer.parseInt(text));
      }
    });

    layerSlider.addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent e) {
        JSlider source = (JSlider) e.getSource();
        chunky.setLayer(source.getValue());
      }
    });

    JLabel coordinatesLbl = new JLabel("Coordinates:");
    JLabel xLbl = new JLabel("X=");
    JLabel zLbl = new JLabel("Z=");
    xField = new JTextField(5);
    xField.addActionListener(coordinateActionListener);
    zField = new JTextField(5);
    zField.addActionListener(coordinateActionListener);

    GroupLayout layout = new GroupLayout(viewPanel);
    viewPanel.setLayout(layout);
    layout.setHorizontalGroup(layout.createParallelGroup()
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup()
          .addComponent(sep1, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
          .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(Alignment.LEADING)
              .addComponent(viewLabel)
              .addComponent(autoModeBtn)
              .addComponent(layerModeBtn)
              .addComponent(surfaceModeBtn)
              .addComponent(caveModeBtn)
              .addComponent(biomeModeBtn))
            .addGap(18)
            .addGroup(layout.createParallelGroup(Alignment.LEADING)
              .addComponent(dimLabel)
              .addComponent(overworldBtn)
              .addComponent(netherBtn)
              .addComponent(endBtn)))
          .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(Alignment.TRAILING, false)
              .addComponent(scaleField, Alignment.LEADING, 0, 0, Short.MAX_VALUE)
              .addComponent(scaleLabel, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addPreferredGap(ComponentPlacement.RELATED)
            .addComponent(scaleSlider, GroupLayout.DEFAULT_SIZE, 202, Short.MAX_VALUE))
          .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(Alignment.TRAILING, false)
              .addComponent(layerField, Alignment.LEADING, 0, 0, Short.MAX_VALUE)
              .addComponent(layerLabel, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addPreferredGap(ComponentPlacement.RELATED)
            .addComponent(layerSlider, GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE))
          .addComponent(coordinatesLbl)
          .addGroup(layout.createSequentialGroup()
            .addComponent(xLbl)
            .addComponent(xField, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(ComponentPlacement.RELATED)
            .addComponent(zLbl)
            .addComponent(zField, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(ComponentPlacement.UNRELATED)
            .addComponent(followPlayer)
          )
        )
        .addContainerGap()
      )
    );
    layout.setVerticalGroup(layout.createParallelGroup()
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addPreferredGap(ComponentPlacement.UNRELATED)
        .addGap(18, 18, 18)
        .addGroup(layout.createParallelGroup(Alignment.BASELINE)
            .addComponent(viewLabel)
            .addComponent(dimLabel))
        .addPreferredGap(ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(Alignment.BASELINE)
            .addComponent(autoModeBtn)
            .addComponent(overworldBtn))
        .addPreferredGap(ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(Alignment.BASELINE)
            .addComponent(layerModeBtn)
            .addComponent(netherBtn))
        .addPreferredGap(ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(Alignment.BASELINE)
            .addComponent(surfaceModeBtn)
            .addComponent(endBtn))
        .addPreferredGap(ComponentPlacement.RELATED)
        .addComponent(caveModeBtn)
        .addPreferredGap(ComponentPlacement.RELATED)
        .addComponent(biomeModeBtn)
        .addPreferredGap(ComponentPlacement.UNRELATED)
        .addComponent(sep1, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(Alignment.TRAILING)
          .addGroup(layout.createSequentialGroup()
            .addComponent(scaleLabel)
            .addPreferredGap(ComponentPlacement.RELATED)
            .addComponent(scaleField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
          .addComponent(scaleSlider, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
        .addGap(18, 18, 18)
        .addGroup(layout.createParallelGroup(Alignment.TRAILING)
          .addGroup(layout.createSequentialGroup()
            .addComponent(layerLabel)
            .addPreferredGap(ComponentPlacement.RELATED)
            .addComponent(layerField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
          .addComponent(layerSlider, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(ComponentPlacement.UNRELATED)
        .addComponent(coordinatesLbl)
        .addPreferredGap(ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(Alignment.BASELINE)
          .addComponent(xLbl)
          .addComponent(xField)
          .addComponent(zLbl)
          .addComponent(zField)
          .addComponent(followPlayer)
        )
        .addContainerGap()
      )
    );

    return viewPanel;
  }

  /**
   * Initialize the edit tab.
   * @param editPanel
   */
  private JComponent buildEditPanel() {
    JComponent editPanel = new JPanel();
    deleteChunksBtn = new JButton();
    progressPanel = new ProgressPanel(chunky.getFrame());

    exportZipBtn = new JButton("Export Chunks to ZIP");
    exportZipBtn.setEnabled(false);
    exportZipBtn.setToolTipText("Export selected chunks or the entire world to a Zip file");
    exportZipBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        CenteredFileDialog fileDialog =
            new CenteredFileDialog(chunky.getFrame(), "Export to ZIP", FileDialog.SAVE);
        fileDialog.setDirectory(System.getProperty("user.dir"));
        fileDialog.setFile(chunky.getWorldName()+".zip");
        fileDialog.setFilenameFilter(
            new FilenameFilter() {
              @Override
              public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".zip");
              }
            });
        fileDialog.setVisible(true);
        File selectedFile = fileDialog.getSelectedFile(".zip");
        if (selectedFile != null) {
          chunky.exportZip(selectedFile, progressPanel);
        }
      }
    });

    JButton renderViewBtn = new JButton();
    renderViewBtn.setText("Render View to PNG");
    renderViewBtn.setToolTipText(
        "Saves the current view as a PNG image");
    renderViewBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        CenteredFileDialog fileDialog =
            new CenteredFileDialog(chunky.getFrame(),
                "Render View", FileDialog.SAVE);
        fileDialog.setDirectory(System.getProperty("user.dir"));
        fileDialog.setFile(chunky.getWorldName()+".png");
        fileDialog.setFilenameFilter(
            new FilenameFilter() {
              @Override
              public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".png");
              }
            });
        fileDialog.setVisible(true);
        File selectedFile = fileDialog.getSelectedFile(".png");
        if (selectedFile != null) {
          chunky.renderView(selectedFile, progressPanel);
        }
      }
    });

    /*JButton renderDimensionBtn = new JButton();
    renderDimensionBtn.setText("Render Dimension to PNG");
    renderDimensionBtn.setToolTipText(
        "Exports the map for the current dimension as a PNG image");
    renderDimensionBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        CenteredFileDialog fileDialog =
            new CenteredFileDialog(chunky.getFrame(),
                "Render Dimension", FileDialog.SAVE);
        fileDialog.setDirectory(System.getProperty("user.dir"));
        fileDialog.setFile(chunky.getWorldDirectory().getName()+".png");
        fileDialog.setFilenameFilter(
            new FilenameFilter() {
              @Override
              public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".png");
              }
            });
        fileDialog.setVisible(true);
        File selectedFile = fileDialog.getSelectedFile(".png");
        if (selectedFile != null)
          chunky.renderDimension(selectedFile, progressPanel);
      }
    });*/

    deleteChunksBtn.setText(Messages.getString("Controls.DeleteSelected_lbl")); //$NON-NLS-1$
    deleteChunksBtn.setEnabled(false);
    deleteChunksBtn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.deleteSelectedChunks();
      }
    });

    clearSelectionBtn2.setText(Messages.getString("Controls.ClearSelected_lbl")); //$NON-NLS-1$
    clearSelectionBtn2.setEnabled(false);
    clearSelectionBtn2.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        chunky.clearSelectedChunks();
      }
    });

    GroupLayout layout = new GroupLayout(editPanel);
    editPanel.setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
          .addContainerGap()
          .addGroup(layout.createParallelGroup(Alignment.LEADING)
            .addComponent(clearSelectionBtn2)
            .addComponent(deleteChunksBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
            .addComponent(progressPanel, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
            .addComponent(exportZipBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
            .addComponent(renderViewBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)
            /*.addComponent(renderDimensionBtn, GroupLayout.DEFAULT_SIZE, WIDTH_BIG, Short.MAX_VALUE)*/)
          .addContainerGap())
      );
    layout.setVerticalGroup(
      layout.createParallelGroup(Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(clearSelectionBtn2)
        .addPreferredGap(ComponentPlacement.RELATED)
        .addComponent(deleteChunksBtn, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(ComponentPlacement.UNRELATED)
        .addComponent(exportZipBtn, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(ComponentPlacement.UNRELATED)
        .addComponent(renderViewBtn, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)
        /*.addPreferredGap(ComponentPlacement.UNRELATED)
        .addComponent(renderDimensionBtn, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)*/
        .addPreferredGap(ComponentPlacement.RELATED, 18, Short.MAX_VALUE)
        .addComponent(progressPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
        .addContainerGap(10, 10))
    );

    return editPanel;
  }

  /**
   * Set the current layer
   * @param y
   */
  public void setLayer(int y) {
    layerField.setText(""+y);
    layerSlider.setValue(y);
  }

  /**
   * Set the map view position
   * @param cx
   * @param y
   * @param cz
   */
  public void setPosition(double cx, int y, double cz) {
    setLayer(y);
    xField.removeActionListener(coordinateActionListener);
    zField.removeActionListener(coordinateActionListener);
    xField.setText(""+(int) (cx*16));
    zField.setText(""+(int) (cz*16));
    xField.addActionListener(coordinateActionListener);
    zField.addActionListener(coordinateActionListener);
  }

  /**
   * Set the map scale
   * @param scale
   */
  public void setScale(int scale) {
    scaleField.setText(""+scale);
    scaleSlider.setValue(scale);
  }

  /**
   * Called when the chunk selection has changed to notify
   * the toolbox if chunks are selected or not
   * @param selected
   */
  public void setChunksSelected(boolean selected) {
    deleteChunksBtn.setEnabled(selected);
    exportZipBtn.setEnabled(selected);
    clearSelectionBtn1.setEnabled(selected);
    clearSelectionBtn2.setEnabled(selected);
    if (selected && tabbedPane.getSelectedIndex() == 0) {
      tabbedPane.setSelectedIndex(RENDER_TAB_INDEX);
    }
  }

  /**
   * Set the player Y position
   * @param layer
   */
  public void setPlayerY(int layer) {
    if (layer >= 0) {
      Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>();
      labelTable.put(layer, new JLabel(faceIcon));
      layerSlider.setLabelTable(labelTable);
      layerSlider.setPaintLabels(true);
    } else {
      layerSlider.setLabelTable(null);
      layerSlider.setPaintLabels(false);
    }
  }

  /**
   * @return The progress panel
   */
  public ProgressPanel getProgressPanel() {
    return progressPanel;
  }

  /**
   * Enable given dimension's check box
   * @param i
   * @param haveDimension
   */
  public void enableDimension(int i, boolean haveDimension) {
    switch (i) {
    case World.OVERWORLD_DIMENSION:
      overworldBtn.setEnabled(haveDimension);
      break;
    case World.NETHER_DIMENSION:
      netherBtn.setEnabled(haveDimension);
      break;
    case World.END_DIMENSION:
      endBtn.setEnabled(haveDimension);
      break;
    }
  }

  /**
   * Open the World Selector dialog.
   */
  public void openWorldSelector() {

    if (worldSelector == null || !worldSelector.isDisplayable()) {
      worldSelector = new WorldSelector(chunky);
    } else if (worldSelector != null) {
      worldSelector.requestFocus();
      worldSelector.toFront();
    }
  }

  final ActionListener coordinateActionListener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
      try {
        int x = Integer.parseInt(xField.getText());
        int z = Integer.parseInt(zField.getText());
        chunky.setView(x/16.0, z/16.0);
        stopFollowingPlayer();
      } catch (NumberFormatException e1) {
      }
    }
  };

  final ActionListener followPlayerListener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
      JCheckBox source = (JCheckBox) e.getSource();
      boolean follow = source.isSelected();
      PersistentSettings.setFollowPlayer(follow);
      if (follow) {
        chunky.goToPlayer();
      }
    }
  };

  public void stopFollowingPlayer() {
    if (followPlayer.isSelected()) {
      followPlayer.removeActionListener(followPlayerListener);
      followPlayer.setSelected(false);
      PersistentSettings.setFollowPlayer(false);
      followPlayer.addActionListener(followPlayerListener);
    }
  }
}
TOP

Related Classes of se.llbit.chunky.ui.Controls

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.