package de.yogularm.minecraft.itemfinder.gui;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import de.yogularm.minecraft.itemfinder.region.ProgressListener;
import de.yogularm.minecraft.itemfinder.region.World;
public class WorldViewer {
private JPanel component;
private JLabel progressLabel;
private ItemList itemList;
private Thread loadThread;
private JProgressBar progressBar;
private World world;
private DimensionSelector dimensionSelector;
private JPanel toolbar;
private static final int PROGRESS_RESOLUTION = 10000;
private JButton reloadButton;
public WorldViewer() {
initUI();
}
public Component getComponent() {
return component;
}
private void initUI() {
component = new JPanel(new BorderLayout(10, 10));
JPanel topPanel = new JPanel(new BorderLayout(10, 10));
component.add(topPanel, BorderLayout.NORTH);
JPanel topRightPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
topPanel.add(topRightPanel, BorderLayout.EAST);
progressBar = new JProgressBar();
progressBar.setPreferredSize(new Dimension(300, 30));
progressBar.setVisible(false);
progressBar.setMaximum(PROGRESS_RESOLUTION);
topRightPanel.add(progressBar);
toolbar = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
toolbar.setVisible(false);
topRightPanel.add(toolbar);
dimensionSelector = new DimensionSelector();
toolbar.add(dimensionSelector.getComponent());
dimensionSelector.addObserver(new Observer() {
@Override
public void update(Observable arg0, Object arg1) {
itemList.setItems(dimensionSelector.getSelection().getDroppedItems());
}
});
reloadButton = new JButton("Reload");
reloadButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
loadWorld(world, true /* force reload */);
}
});
// spacing between button and combobox
JPanel reloadButtonPanel = new JPanel(new BorderLayout());
reloadButtonPanel.setBorder(new EmptyBorder(0, 10, 0, 0));
reloadButtonPanel.add(reloadButton);
toolbar.add(reloadButtonPanel);
progressLabel = new JLabel("Please select a world");
progressLabel.setFont(progressLabel.getFont().deriveFont(Font.BOLD));
topPanel.add(progressLabel, BorderLayout.CENTER);
itemList = new ItemList();
component.add(itemList.getComponent(), BorderLayout.CENTER);
}
private void loadWorld(final World world, boolean forceReload) {
if (loadThread != null && loadThread.isAlive())
loadThread.interrupt();
if (!forceReload && world.isLoaded()) {
onLoaded(world);
return;
}
progressLabel.setText(world.getDisplayName() + ": Loading...");
loadThread = new Thread(new Runnable() {
@Override
public void run() {
try {
world.load(new WorldLoadProgressListener(world));
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (!Thread.currentThread().isInterrupted())
onLoaded(world);
}
});
} catch (IOException e) {
if (!Thread.currentThread().isInterrupted()) {
finishProgress();
progressLabel.setText("Error loading " + world.getDisplayName());
JOptionPane.showMessageDialog(null,
"Error loading world: " + e.getMessage());
}
} catch (InterruptedException e) {
// do nothing
}
}
});
initProgress();
loadThread.setDaemon(true); // don't block program termination
loadThread.start();
}
private void onLoaded(World world) {
this.world = world;
finishProgress();
toolbar.setVisible(true);
progressLabel.setText(world.getDisplayName());
dimensionSelector.setDimensions(world.getDimensions());
}
public void setWorld(final World world) {
loadWorld(world, false);
}
private void initProgress() {
progressBar.setValue(0);
progressBar.setVisible(true);
toolbar.setVisible(false);
}
private void finishProgress() {
progressBar.setVisible(false);
}
private class WorldLoadProgressListener implements ProgressListener {
private World world;
public WorldLoadProgressListener(World world) {
this.world = world;
}
@Override
public void onAction(String action) {
if (!Thread.currentThread().isInterrupted())
progressLabel.setText(world.getDisplayName() + ": " + action);
}
@Override
public void onProgress(double progress) {
if (!Thread.currentThread().isInterrupted())
progressBar.setValue((int)(progress * PROGRESS_RESOLUTION));
}
}
}