/**
* Copyright 2012 Tobias Gierke <tobias.gierke@code-sourcery.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.codesourcery.jasm16.ide.ui.utils;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang.StringUtils;
import de.codesourcery.jasm16.ide.IAssemblyProject;
public class UIUtils {
public static enum DialogResult {
YES,
NO,
CANCEL;
}
public static void invokeAndWait(Runnable r) {
if ( SwingUtilities.isEventDispatchThread() ) {
r.run();
} else {
try {
SwingUtilities.invokeAndWait( r );
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getCause());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public static void invokeLater(Runnable r) {
if ( SwingUtilities.isEventDispatchThread() ) {
r.run();
} else {
SwingUtilities.invokeLater( r );
}
}
public static void setBlockAllUserInput(final JFrame frame , final boolean yesNo)
{
invokeAndWait( new Runnable() {
@Override
public void run()
{
frame.getGlassPane().setVisible( yesNo );
}
} );
}
public static DialogResult showConfirmationDialog(Component parent, String title,String message) {
final Object[] options = {"Yes","No","Cancel"};
final int outcome = JOptionPane.showOptionDialog(parent,message,
title,
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[2]);
switch( outcome ) {
case 0:
return DialogResult.YES;
case 1:
return DialogResult.NO;
case 2:
case JOptionPane.CLOSED_OPTION:
return DialogResult.CANCEL;
default:
throw new RuntimeException("Internal error, unexpected outcome "+outcome);
}
}
/**
*
* @param parent
* @param title
* @param message
* @return <code>true</code> if project should also be physically deleted,
* <code>false</code> is project should be deleted but all files should be left alone,
* <code>null</code> if user cancelled the dialog/project should not be deleted
*/
public static Boolean showDeleteProjectDialog(IAssemblyProject project)
{
final JDialog dialog = new JDialog( (Window) null, "Delete project "+project.getName());
dialog.setModal( true );
final JTextArea message = createMultiLineLabel( "Do you really want to delete project '"+project.getName()+" ?");
final JCheckBox checkbox = new JCheckBox("Delete project files");
final DialogResult[] outcome = { DialogResult.CANCEL };
final JButton yesButton = new JButton("Yes");
yesButton.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
outcome[0] = DialogResult.YES;
dialog.dispose();
}
});
final JButton noButton = new JButton("No");
noButton.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
outcome[0] = DialogResult.NO;
dialog.dispose();
}
});
final JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
outcome[0] = DialogResult.CANCEL;
dialog.dispose();
}
});
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new FlowLayout() );
buttonPanel.add( yesButton );
buttonPanel.add( noButton );
buttonPanel.add( cancelButton );
final JPanel messagePanel = new JPanel();
messagePanel.setLayout( new GridBagLayout() );
GridBagConstraints cnstrs = constraints(0,0,true,false, GridBagConstraints.NONE );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.weighty=0;
cnstrs.gridheight = 1;
messagePanel.add( message , cnstrs );
cnstrs = constraints(0,1,true,true, GridBagConstraints.NONE );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.gridheight = 1;
cnstrs.weighty=0;
messagePanel.add( checkbox , cnstrs );
final JPanel panel = new JPanel();
panel.setLayout( new GridBagLayout() );
cnstrs = constraints(0,0,true,false , GridBagConstraints.NONE );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.gridheight = 1;
cnstrs.weighty=0;
cnstrs.insets = new Insets(5,2,5,2); // top,left,bottom,right
panel.add( messagePanel , cnstrs );
cnstrs = constraints(0,1,true,true, GridBagConstraints.HORIZONTAL );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.gridheight = 1;
cnstrs.weighty=0;
cnstrs.insets = new Insets(0,2,10,2); // top,left,bottom,right
panel.add( buttonPanel , cnstrs );
dialog.getContentPane().add( panel );
dialog.pack();
dialog.setVisible( true );
if ( outcome[0] != DialogResult.YES ) {
return null;
}
return checkbox.isSelected();
}
private static final ExecutorService pool = new ThreadPoolExecutor( 4 , 4 , 60 , TimeUnit.SECONDS , new ArrayBlockingQueue<Runnable>(100) );
public static void executeAsynchronously(Runnable r) {
pool.submit( r );
}
public static JFrame createMessageFrame(String title,String msg) {
final JFrame frame = new JFrame( title );
final JTextArea message = createMultiLineLabel( msg );
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new FlowLayout() );
final JPanel messagePanel = new JPanel();
messagePanel.setLayout( new GridBagLayout() );
GridBagConstraints cnstrs = constraints(0,0,true,false, GridBagConstraints.NONE );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.weighty=0;
cnstrs.gridheight = 1;
messagePanel.add( message , cnstrs );
final JPanel panel = new JPanel();
panel.setLayout( new GridBagLayout() );
cnstrs = constraints(0,0,true,false , GridBagConstraints.NONE );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.gridheight = 1;
cnstrs.weighty=0;
cnstrs.insets = new Insets(5,2,5,2); // top,left,bottom,right
panel.add( messagePanel , cnstrs );
cnstrs = constraints(0,1,true,true, GridBagConstraints.HORIZONTAL );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.gridheight = 1;
cnstrs.weighty=0;
cnstrs.insets = new Insets(0,2,10,2); // top,left,bottom,right
panel.add( buttonPanel , cnstrs );
frame.getContentPane().add( panel );
frame.pack();
return frame;
}
public static JDialog createMessageDialog(Window parent,String title,String msg) {
final JDialog dialog = new JDialog( parent , title );
final JTextArea message = createMultiLineLabel( msg );
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new FlowLayout() );
final JPanel messagePanel = new JPanel();
messagePanel.setLayout( new GridBagLayout() );
GridBagConstraints cnstrs = constraints(0,0,true,false, GridBagConstraints.NONE );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.weighty=0;
cnstrs.gridheight = 1;
messagePanel.add( message , cnstrs );
final JPanel panel = new JPanel();
panel.setLayout( new GridBagLayout() );
cnstrs = constraints(0,0,true,false , GridBagConstraints.NONE );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.gridheight = 1;
cnstrs.weighty=0;
cnstrs.insets = new Insets(5,2,5,2); // top,left,bottom,right
panel.add( messagePanel , cnstrs );
cnstrs = constraints(0,1,true,true, GridBagConstraints.HORIZONTAL );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.gridheight = 1;
cnstrs.weighty=0;
cnstrs.insets = new Insets(0,2,10,2); // top,left,bottom,right
panel.add( buttonPanel , cnstrs );
dialog.getContentPane().add( panel );
dialog.pack();
return dialog;
}
public static String showInputDialog(Component parent,String title,String message) {
Object[] possibilities = null;
String s = (String) JOptionPane.showInputDialog(
parent,
message,
title,
JOptionPane.PLAIN_MESSAGE,
null,
possibilities,
null);
return StringUtils.isNotBlank( s ) ? s : null;
}
public static void showErrorDialog(Component parent,String title,String message) {
showErrorDialog(parent, title, message,null);
}
public static void showErrorDialog(Component parent,String title,String textMessage,Throwable cause)
{
final String stacktrace;
if ( cause == null ) {
stacktrace = null;
} else {
final ByteArrayOutputStream stackTrace = new ByteArrayOutputStream();
cause.printStackTrace( new PrintStream( stackTrace ) );
stacktrace = new String(stackTrace.toByteArray());
}
final JDialog dialog = new JDialog( (Window) null, title );
dialog.setModal( true );
final JTextArea message = createMultiLineLabel( textMessage );
final DialogResult[] outcome = { DialogResult.CANCEL };
final JButton okButton = new JButton("Ok");
okButton.addActionListener( new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
outcome[0] = DialogResult.YES;
dialog.dispose();
}
});
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new FlowLayout() );
buttonPanel.add( okButton );
final JPanel messagePanel = new JPanel();
messagePanel.setLayout( new GridBagLayout() );
GridBagConstraints cnstrs = constraints(0,0,true,true, GridBagConstraints.BOTH );
cnstrs.weightx=1;
cnstrs.weighty=0.1;
cnstrs.gridheight = 1;
messagePanel.add( message , cnstrs );
if ( stacktrace != null )
{
final JTextArea createMultiLineLabel = new JTextArea( stacktrace );
createMultiLineLabel.setBackground(null);
createMultiLineLabel.setEditable(false);
createMultiLineLabel.setBorder(null);
createMultiLineLabel.setLineWrap(false);
createMultiLineLabel.setWrapStyleWord(false);
final JScrollPane pane = new JScrollPane( createMultiLineLabel ,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED , JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
cnstrs = constraints(0,1,true,true, GridBagConstraints.BOTH );
cnstrs.weightx=1.0;
cnstrs.weighty=0.9;
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.gridheight = GridBagConstraints.REMAINDER;
messagePanel.add( pane , cnstrs );
}
final JPanel panel = new JPanel();
panel.setLayout( new GridBagLayout() );
cnstrs = constraints(0,0,true,false , GridBagConstraints.BOTH );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.gridheight = 1;
cnstrs.weighty=1.0;
cnstrs.insets = new Insets(5,2,5,2); // top,left,bottom,right
panel.add( messagePanel , cnstrs );
cnstrs = constraints(0,1,true,true, GridBagConstraints.HORIZONTAL );
cnstrs.gridwidth = GridBagConstraints.REMAINDER;
cnstrs.gridheight = 1;
cnstrs.weighty=0;
cnstrs.insets = new Insets(0,2,10,2); // top,left,bottom,right
panel.add( buttonPanel , cnstrs );
dialog.getContentPane().add( panel );
dialog.setMinimumSize(new Dimension(600,400));
dialog.setPreferredSize(new Dimension(600,400));
dialog.setMaximumSize(new Dimension(600,400));
dialog.pack();
dialog.setVisible( true );
}
protected static final GridBagConstraints constraints(int x,int y,boolean remainderHoriz,boolean remainderVert,int fill) {
final GridBagConstraints cnstrs = new GridBagConstraints();
cnstrs.anchor = GridBagConstraints.NORTHWEST;
cnstrs.weightx=1.0d;
cnstrs.weighty =1.0d;
cnstrs.fill = fill;
cnstrs.gridheight = remainderVert ? GridBagConstraints.REMAINDER : 1;
cnstrs.gridwidth = remainderHoriz ? GridBagConstraints.REMAINDER : 1;
cnstrs.gridx=x;
cnstrs.gridy=y;
cnstrs.insets = new Insets(10,2,10,2); // top,left,bottom,right
return cnstrs;
}
public static JTextArea createMultiLineLabel(String text) {
return new TextNote( text );
}
public static final class TextNote extends JTextArea
{
public TextNote(String text) {
super(text);
setColumns( text.length() );
setBackground(null);
setEditable(false);
setBorder(null);
setLineWrap(true);
setWrapStyleWord(true);
setFocusable(false);
}
}
}