How do I add a toolbar with controls to the DefaultInformationControl? - java

What I managed to do so far is adding a ToolBarManager for the ToolBar I created, which contains the ToolItem I want to add but nothing is shown when the hover popup based on this DefaultInformationControl is open.
I gave all the ToolItems text and style.
My code is :
public class JavaTextHover implements IJavaEditorTextHover, ITextHoverExtension{
.
.
.
#Override
public IInformationControlCreator getHoverControlCreator() {
return new IInformationControlCreator() {
public IInformationControl createInformationControl(Shell parent) {
ToolBar toolBar = new ToolBar(parent, SWT.NONE);
ToolItem itemPush = new ToolItem(toolBar, SWT.PUSH);
itemPush.setText("PUSH item");
ToolItem itemCheck = new ToolItem(toolBar, SWT.CHECK);
itemCheck.setText("CHECK item");
ToolItem itemRadio1 = new ToolItem(toolBar, SWT.RADIO);
itemRadio1.setText("RADIO item 1");
ToolItem itemRadio2 = new ToolItem(toolBar, SWT.RADIO);
itemRadio2.setText("RADIO item 2");
ToolItem itemSeparator = new ToolItem(toolBar, SWT.SEPARATOR);
Text text = new Text(toolBar, SWT.BORDER | SWT.SINGLE);
text.pack();
itemSeparator.setWidth(text.getBounds().width);
itemSeparator.setControl(text);
final ToolItem itemDropDown = new ToolItem(toolBar, SWT.DROP_DOWN);
itemDropDown.setText("DROP_DOWN item");
itemDropDown.setToolTipText("Click here to see a drop down menu ...");
final Menu menu = new Menu(parent, SWT.POP_UP);
new MenuItem(menu, SWT.PUSH).setText("Menu item 1");
new MenuItem(menu, SWT.PUSH).setText("Menu item 2");
new MenuItem(menu, SWT.SEPARATOR);
new MenuItem(menu, SWT.PUSH).setText("Menu item 3");
itemDropDown.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if(event.detail == SWT.ARROW) {
Rectangle bounds = itemDropDown.getBounds();
Point point = toolBar.toDisplay(bounds.x, bounds.y + bounds.height);
menu.setLocation(point);
menu.setVisible(true);
}
}
});
Listener selectionListener = new Listener() {
public void handleEvent(Event event) {
ToolItem item = (ToolItem)event.widget;
System.out.println(item.getText() + " is selected");
if( (item.getStyle() & SWT.RADIO) != 0 || (item.getStyle() & SWT.CHECK) != 0 )
System.out.println("Selection status: " + item.getSelection());
}
};
itemPush.addListener(SWT.Selection, selectionListener);
itemCheck.addListener(SWT.Selection, selectionListener);
itemRadio1.addListener(SWT.Selection, selectionListener);
itemRadio2.addListener(SWT.Selection, selectionListener);
itemDropDown.addListener(SWT.Selection, selectionListener);
toolBar.pack();
toolBar.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,false));
ToolBarManager tbm=new ToolBarManager(toolBar);
System.out.println(tbm.getControl().getChildren().length);
DefaultInformationControl dic=new DefaultInformationControl(parent, tbm);
dic.setBackgroundColor(new Color(null, 98,201,145));
return dic;
}
};
}
.
.
.
}

The only example of using the tool bar that I can see in the Eclipse core code does things this way:
private static final class PresenterControlCreator extends AbstractReusableInformationControlCreator {
#Override
public IInformationControl doCreateInformationControl(Shell parent) {
ToolBarManager tbm= new ToolBarManager(SWT.FLAT);
NLSHoverControl iControl= new NLSHoverControl(parent, tbm);
OpenPropertiesFileAction openPropertiesFileAction= new OpenPropertiesFileAction(iControl);
tbm.add(openPropertiesFileAction);
tbm.update(true);
return iControl;
}
}
NLSHoverControl extends DefaultInformationControl.
So it is adding to the tool bar after creating the DefaultInformationControl and using actions rather than tool items.
static class NLSHoverControl extends DefaultInformationControl implements IInformationControlExtension2 {
/**
* The NLS control input.
*/
private NLSHoverControlInput fInput;
/**
* Creates a resizable NLS hover control with the given shell as parent.
*
* #param parent the parent shell
* #param tbm the toolbar manager or <code>null</code> if toolbar is not desired
*/
public NLSHoverControl(Shell parent, ToolBarManager tbm) {
super(parent, tbm);
}
/**
* Creates an NLS hover control with the given shell as parent.
*
* #param parent the parent shell
* #param tooltipAffordanceString the text to be used in the status field or
* <code>null</code> to hide the status field
*/
public NLSHoverControl(Shell parent, String tooltipAffordanceString) {
super(parent, tooltipAffordanceString);
}
/**
* {#inheritDoc} This control can handle {#link NLSStringHover.NLSHoverControlInput}.
*/
public void setInput(Object input) {
Assert.isLegal(input instanceof NLSHoverControlInput);
NLSHoverControlInput info= (NLSHoverControlInput)input;
setInformation(info.fInformation);
fInput= info;
}
/**
* Returns the control input.
*
* #return the control input
*/
public NLSHoverControlInput getInput() {
return fInput;
}
}

Related

TreeTableView TableMenuButton setonAction

Is there any possible way to listen or to override the default TableMenuButton setonAction?
Something like this?
TreeTableView ttv = new TreeTableView();
ttv.setTableMenuButtonVisible(true);
ttv.setOnMouseClicked((MouseEvent event) -> {
....
});
I would like to know which column has been set to visible or invisible.
Any help is greatly appreciated.
I created an example about how to adapt the TableView's menu button. The TreeTableView is just similar. What you need to do is to get the ContextMenu. You can get it either by reflection or by using a lookup. Once you have it, you can do whatever you want with it.
I also filed a change request so that the context menu becomes accessible since the current implementation isn't satisfactory.
Here's the modified code of the lookup version:
public class TableUtils {
/**
* Make table menu button visible and replace the context menu with a custom context menu via reflection.
* The preferred height is modified so that an empty header row remains visible. This is needed in case you remove all columns, so that the menu button won't disappear with the row header.
* IMPORTANT: Modification is only possible AFTER the table has been made visible, otherwise you'd get a NullPointerException
* #param tableView
*/
public static void addCustomTableMenu( TreeTableView tableView) {
// enable table menu
tableView.setTableMenuButtonVisible(true);
// replace internal mouse listener with custom listener
setCustomContextMenu( tableView);
}
private static void setCustomContextMenu( TreeTableView table) {
TreeTableViewSkin<?> tableSkin = (TreeTableViewSkin<?>) table.getSkin();
// get all children of the skin
ObservableList<Node> children = tableSkin.getChildren();
// find the TableHeaderRow child
for (int i = 0; i < children.size(); i++) {
Node node = children.get(i);
if (node instanceof TableHeaderRow) {
TableHeaderRow tableHeaderRow = (TableHeaderRow) node;
// setting the preferred height for the table header row
// if the preferred height isn't set, then the table header would disappear if there are no visible columns
// and with it the table menu button
// by setting the preferred height the header will always be visible
// note: this may need adjustments in case you have different heights in columns (eg when you use grouping)
double defaultHeight = tableHeaderRow.getHeight();
tableHeaderRow.setPrefHeight(defaultHeight);
for( Node child: tableHeaderRow.getChildren()) {
// child identified as cornerRegion in TableHeaderRow.java
if( child.getStyleClass().contains( "show-hide-columns-button")) {
// get the context menu
ContextMenu columnPopupMenu = createContextMenu( table);
// replace mouse listener
child.setOnMousePressed(me -> {
// show a popupMenu which lists all columns
columnPopupMenu.show(child, Side.BOTTOM, 0, 0);
me.consume();
});
}
}
}
}
}
/**
* Create a menu with custom items. The important thing is that the menu remains open while you click on the menu items.
* #param cm
* #param table
*/
private static ContextMenu createContextMenu( TreeTableView table) {
ContextMenu cm = new ContextMenu();
// create new context menu
CustomMenuItem cmi;
// select all item
Label showAll = new Label("Show all");
showAll.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
for (Object obj : table.getColumns()) {
((TreeTableColumn<?, ?>) obj).setVisible(true);
}
}
});
cmi = new CustomMenuItem(showAll);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
// deselect all item
Label hideAll = new Label("Hide all");
hideAll.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
for (Object obj : table.getColumns()) {
((TreeTableColumn<?, ?>) obj).setVisible(false);
}
}
});
cmi = new CustomMenuItem(hideAll);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
// separator
cm.getItems().add(new SeparatorMenuItem());
// menu item for each of the available columns
for (Object obj : table.getColumns()) {
TreeTableColumn<?, ?> tableColumn = (TreeTableColumn<?, ?>) obj;
CheckBox cb = new CheckBox(tableColumn.getText());
cb.selectedProperty().bindBidirectional(tableColumn.visibleProperty());
cmi = new CustomMenuItem(cb);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
}
return cm;
}
}

SWT MessageBox with custom button titles

I want to add the custom button titles in my non-RCP SWT app.
MessageBox messageBox = new MessageBox(shell, SWT.ICON_WARNING | SWT.ABORT | SWT.RETRY | SWT.IGNORE);
messageBox.setText("Warning");
messageBox.setMessage("Save the changes before exiting?");
int buttonID = messageBox.open();
switch(buttonID) {
case SWT.YES:
// saves changes ...
case SWT.NO:
// exits here ...
break;
case SWT.CANCEL:
// does nothing ...
}
System.out.println(buttonID);
}
It works fine but i button titles are "Abort", "Retry", "ignore"
I want custom button titles, like "overwrite", "rename", "cancel".
How it can be done?
Please help.
*** EDIT ********
I also tried
MessageDialog dialog = new MessageDialog(null, "Dangerous Activity", null,
"Are you sure you want to delete?", MessageDialog.CONFIRM,
new String[]{"Preview>", "Delete", "Cancel"}, 0)
{
protected void buttonPressed(int buttonId) {
setReturnCode(buttonId);
// close(); Call close for Delete or Cancel?
}};
But MessageDialog requires app to be RCP, therefore not importing the package required. Help.
Here is a very simple example on how to do your own Dialog in SWT (there are more comfortable ways to do this with JFace though):
public class CustomDialog extends Dialog
{
private String message = "";
private Shell shell;
public CustomDialog(Shell parent)
{
// Pass the default styles here
this(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
shell = parent;
}
public CustomDialog(Shell parent, int style)
{
// Let users override the default styles
super(parent, style);
shell = parent;
}
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}
public void open()
{
shell.setText(getText());
createContents(shell);
shell.pack();
shell.open();
Display display = getParent().getDisplay();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
}
/**
* Creates the dialog's contents
*
* #param shell
* the dialog window
*/
private void createContents(final Shell shell)
{
shell.setLayout(new GridLayout(3, true));
// Show the message
Label label = new Label(shell, SWT.NONE);
label.setText(message);
GridData data = new GridData();
data.horizontalSpan = 3;
label.setLayoutData(data);
// Display the input box
Label image = new Label(shell, SWT.NONE);
image.setImage(shell.getDisplay().getSystemImage(SWT.ICON_ERROR));
data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
data.horizontalSpan = 3;
image.setLayoutData(data);
Button preview = new Button(shell, SWT.PUSH);
preview.setText("Preview");
data = new GridData(SWT.FILL, SWT.END, true, true);
preview.setLayoutData(data);
preview.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent event)
{
System.out.println("Preview");
}
});
Button delete = new Button(shell, SWT.PUSH);
delete.setText("Delete");
data = new GridData(SWT.FILL, SWT.END, true, true);
delete.setLayoutData(data);
delete.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent event)
{
System.out.println("Delete");
}
});
Button cancel = new Button(shell, SWT.PUSH);
cancel.setText("Cancel");
data = new GridData(SWT.FILL, SWT.END, true, true);
cancel.setLayoutData(data);
cancel.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent event)
{
shell.close();
}
});
shell.setDefaultButton(preview);
}
public static void main(String[] args)
{
CustomDialog dialog = new CustomDialog(new Shell());
dialog.setText("Title");
dialog.setMessage("Message");
dialog.open();
}
}
It looks like this:
MessageBox cannot be extended this way. Your best option - when not doing an RCP application - probably is to roll your own dialog :-)
But given the simple nature of these dialogs, that should be easy enough.
I'm a little late to this, but if anyone else is looking for a cutomizable MessageBox, here it is. Create a class, then copy/paste the code into it. I want to thank Baz for giving me the starting point :-)
import java.util.ArrayList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
/**
* Custom MessageBox which allows custom button captions, such as using language specific text<br>
* <br>
* <code><b>
* int cancelResult = 0;<br>
* int deleteResult = 1;<br>
* <br>
* CustomMessageBox messageBox = new CustomMessageBox( ivShell, CustomMessageBox.ImageCode.QUESTION, "Confirm Delete", "Are you sure you want to delete:\n\n" + key );<br>
* <br>
* messageBox.addButton( "Cancel", cancelResult, true );<br>
* messageBox.addButton( "Delete " + key, deleteResult );<br>
* <br>
* if (messageBox.getResult() == deleteResult)<br>
* remove( key );<br>
* </b></code>
*/
public class CustomMessageBox extends Dialog
{
/**
* Standard SWT icons used in a message box
*/
public enum ImageCode
{
INFORMATION(SWT.ICON_INFORMATION),
QUESTION(SWT.ICON_QUESTION),
WARNING(SWT.ICON_WARNING),
ERROR(SWT.ICON_ERROR);
private int ivImageCode;
private ImageCode( int imageCode )
{
ivImageCode = imageCode;
}
private int getImageCode()
{
return ivImageCode;
}
}
private static final int FORM_SPACING = 5;
private static final String OK_CAPTION = "Ok"; //$NON-NLS-1$
private static final int SCREEN_MINIMUM = 20;
private Shell ivParentShell;
private Shell ivShell;
private Composite ivCompositeImage;
private Composite ivCompositeMessage;
private Composite ivCompositeDummy;
private Composite ivCompositeButtons;
private Label ivLabelImage;
private Label ivLabelMessage;
private Color ivMessageForegroundColor;
private Color ivMessageBackgroundColor;
private Font ivMessageFont;
private ImageCode ivImageCode;
private String ivTitle;
private String ivMessage;
private ArrayList<ButtonParameter> ivButtons;
private int ivResult;
/**
* Create a custom message box. You must {#link #addButton(String, int, boolean)} before calling {#link #getResult()}
* #param parentShell - the parent shell. The message box will be centered within this shell
* #param imageCode - the image to be shown in the upper/left corner
* #param title - the title for the message box
* #param message - the message shown to the user. You can have newlines in the message
*/
public CustomMessageBox( Shell parentShell, ImageCode imageCode, String title, String message )
{
super( parentShell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL );
ivParentShell = parentShell;
ivImageCode = imageCode;
ivTitle = title;
ivMessage = message;
ivButtons = new ArrayList<>();
ivMessageForegroundColor = null;
ivMessageBackgroundColor = null;
ivMessageFont = null;
}
/**
* Buttons are created right to left, so add the right-most button first. This will not be the default button
* #param caption - the caption for the button
* #param result - the returned result when the button is chosen. Should be unique!
*/
public void addButton( String caption, int result )
{
addButton( caption, result, false );
}
/**
* Buttons are created right to left, so add the right-most button first.<br><br>
* If more than one button is set to be the default or no buttons are set to be the default, then the last one added will actually become the default.
* #param caption - the caption for the button
* #param result - the returned result when the button is chosen. Should be unique!
* #param isDefault - this will be the default button.
*/
public void addButton( String caption, int result, boolean isDefault )
{
ivButtons.add( new ButtonParameter( caption, result, isDefault ) );
}
/**
* Set the message foreground color
* #param foregroundColor
*/
public void setMessageForegroundColor( Color foregroundColor )
{
ivMessageForegroundColor = foregroundColor;
}
/**
* Set the message background color
* #param backgroundColor
*/
public void setMessageBackgroundColor( Color backgroundColor )
{
ivMessageBackgroundColor = backgroundColor;
}
/**
* Set the message font
* #param messageFont
*/
public void setMessageFont( Font messageFont )
{
ivMessageFont = messageFont;
}
/**
* Open the window and get the result. If no buttons were added, a stock "Ok" button will be created
*/
public int getResult()
{
Display display = Display.getDefault();
// bad programmer, bad
if (ivButtons.size() == 0)
addButton( OK_CAPTION, 0, true );
ivShell = new Shell( SWT.BORDER | SWT.TITLE | SWT.APPLICATION_MODAL );
createContents( display );
ivShell.pack();
ivShell.setLocation( centerOnParent( ivParentShell, ivShell ) );
ivShell.open();
while (!ivShell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
return ivResult;
}
/**
* Centers the message box within the parent shell
*/
private Point centerOnParent( Shell parentShell, Shell childShell )
{
Rectangle parent = parentShell.getBounds();
Rectangle child = childShell.getBounds();
int x = (int) (parent.x + (parent.width - child.width) * 0.5f);
int y = (int) (parent.y + (parent.height - child.height) * 0.5f);
// just to keep the left edge on the screen
if (x < SCREEN_MINIMUM)
x = SCREEN_MINIMUM;
// just to keep the top edge on the screen
if (y < SCREEN_MINIMUM)
y = SCREEN_MINIMUM;
return new Point( x, y );
}
/**
* Creates the contents and places them in the shell
*/
private void createContents( Display display )
{
FormData formData;
GridData gridData;
Button button;
Button lastButton;
ivShell.setLayout( new GridLayout( 2, false ) );
ivShell.setText( ivTitle );
{
ivCompositeImage = new Composite( ivShell, SWT.NONE );
ivCompositeImage.setLayout( new FormLayout() );
gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.grabExcessVerticalSpace = true;
gridData.verticalAlignment = SWT.TOP;
gridData.horizontalAlignment = SWT.LEFT;
ivCompositeImage.setLayoutData( gridData );
}
{
ivCompositeMessage = new Composite( ivShell, SWT.NONE );
ivCompositeMessage.setLayout( new FormLayout() );
gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.grabExcessVerticalSpace = true;
ivCompositeMessage.setLayoutData( gridData );
}
{
ivCompositeDummy = new Composite( ivShell, SWT.NONE );
ivCompositeDummy.setLayout( new FormLayout() );
}
{
ivCompositeButtons = new Composite( ivShell, SWT.NONE );
ivCompositeButtons.setLayout( new FormLayout() );
gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.grabExcessVerticalSpace = true;
gridData.horizontalAlignment = SWT.END;
ivCompositeButtons.setLayoutData( gridData );
}
{
ivLabelImage = new Label( ivCompositeImage, SWT.NONE );
formData = new FormData();
formData.top = new FormAttachment( 0, 0 );
formData.left = new FormAttachment( 0, 0 );
ivLabelImage.setLayoutData( formData );
ivLabelImage.setImage( display.getSystemImage( ivImageCode.getImageCode() ) );
}
{
ivLabelMessage = new Label( ivCompositeMessage, SWT.WRAP );
formData = new FormData();
formData.top = new FormAttachment( 0, 0 );
formData.left = new FormAttachment( 0, 0 );
formData.right = new FormAttachment( 100, 0 );
formData.bottom = new FormAttachment( 100, 0 );
ivLabelMessage.setLayoutData( formData );
// we add a new line to place white-space between the message and the buttons
// the trailing space is required!
ivLabelMessage.setText( ivMessage + System.getProperty( "line.separator" ) + " " ); //$NON-NLS-1$ //$NON-NLS-2$
if (ivMessageForegroundColor != null)
ivLabelMessage.setForeground( ivMessageForegroundColor );
if (ivMessageBackgroundColor != null)
ivLabelMessage.setBackground( ivMessageBackgroundColor );
if (ivMessageFont != null)
ivLabelMessage.setFont( ivMessageFont );
}
lastButton = null;
for (ButtonParameter parm : ivButtons)
{
button = new Button( ivCompositeButtons, SWT.PUSH );
formData = new FormData();
if (lastButton == null)
formData.right = new FormAttachment( 100, -FORM_SPACING );
else
formData.right = new FormAttachment( lastButton, -FORM_SPACING, SWT.LEFT );
formData.bottom = new FormAttachment( 100, -FORM_SPACING );
button.setLayoutData( formData );
button.setText( parm.getCaption() );
button.addMouseListener( new ButtonMouseListener( parm.getResult() ) );
lastButton = button;
if (parm.isDefault())
ivShell.setDefaultButton( button );
}
if (ivShell.getDefaultButton() == null)
ivShell.setDefaultButton( lastButton );
}
/**
* Internal class which holds the button parameters. This is created by the {#link CustomMessageBox#addButton(String, int, boolean)} method
*/
private class ButtonParameter
{
private String ivCaption;
private int ivResult;
private boolean ivIsDefault;
/**
* Create a button parameter
* #param caption - the caption for the button
* #param result - the returned result when the button is chosen
* #param isDefault - this will be the default button.
*/
private ButtonParameter( String caption, int result, boolean isDefault )
{
super();
ivCaption = caption;
ivResult = result;
ivIsDefault = isDefault;
}
private String getCaption()
{
return ivCaption;
}
private int getResult()
{
return ivResult;
}
private boolean isDefault()
{
return ivIsDefault;
}
}
/**
* Mouse listener for the buttons.
*/
private class ButtonMouseListener extends MouseAdapter
{
private int ivButtonResult;
/**
* Creates the listener
* #param result - The result returned when the button is pressed
*/
private ButtonMouseListener( int result )
{
super();
ivButtonResult = result;
}
#Override
public void mouseUp( MouseEvent e )
{
ivResult = ivButtonResult;
ivShell.close();
}
}
}

Java Battleships Issues

I have to design a batleships game for friday but the course im doing seems to have skipped a few things because although i managed all the other assignments this final project is unbelievably above my grasp but i have to do something.
i have the following GUI code which gives me my playing grids but i have absolutely no idea how to do the following things
assign a ship to some cells - and color these cells to reflect this
how to do the actual hit,miss,sunk and update the grid
i figure if i can at least do these i can duplicate the code for the cpu but im sooooooo stuck so any help is really appreciated please guys work some magic :)
/**
* BattleGui:
*
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
public class BattleGui implements ActionListener
{
// Default filename to use for saving and loading files
// Possible improvement: replace with a FileChooser
private final static String DEFAULT_FILENAME = "battlegui.txt";
private int GRID_SIZE = 8;
private JButton [] buttonArray;
public JMenuBar createMenu()
{
JMenuBar menuBar = new JMenuBar();;
JMenu menu = new JMenu("Battle Menu");
JMenuItem menuItem;
menuBar.add(menu);
// A group of JMenuItems. You can create other menu items here if desired
menuItem = new JMenuItem("New Game");
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Load Game");
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Save Game");
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Quit");
menuItem.addActionListener(this);
menu.add(menuItem);
//a submenu
menu.addSeparator();
return menuBar;
}
public Container createContentPaneCPU()
{
int numButtons = GRID_SIZE * GRID_SIZE;
JPanel grid = new JPanel(new GridLayout(GRID_SIZE,GRID_SIZE));
buttonArray = new JButton[numButtons];
for (int i=0; i<numButtons; i++)
{
buttonArray[i] = new JButton(" ");
// This label is used to identify which button was clicked in the action listener
buttonArray[i].setActionCommand("" + i); // String "0", "1" etc.
buttonArray[i].addActionListener(this);
grid.add(buttonArray[i]);
}
return grid;
}
public Container createContentPane()
{
int numButtons = GRID_SIZE * GRID_SIZE;
JPanel grid = new JPanel(new GridLayout(GRID_SIZE,GRID_SIZE));
buttonArray = new JButton[numButtons];
for (int i=0; i<numButtons; i++)
{
buttonArray[i] = new JButton(" ");
// This label is used to identify which button was clicked in the action listener
//buttonArray[i].setActionCommand("" + i); // String "0", "1" etc.
// buttonArray[i].addActionListener(this);
grid.add(buttonArray[i]);
}
return grid;
}
/**
* This method handles events from the Menu and the board.
*
*/
public void actionPerformed(ActionEvent e)
{
String classname = getClassName(e.getSource());
JComponent component = (JComponent)(e.getSource());
if (classname.equals("JMenuItem"))
{
JMenuItem menusource = (JMenuItem)(e.getSource());
String menutext = menusource.getText();
// Determine which menu option was chosen
if (menutext.equals("Load Game"))
{
/* BATTLEGUI Add your code here to handle Load Game **********/
LoadGame();
}
else if (menutext.equals("Save Game"))
{
/* BATTLEGUI Add your code here to handle Save Game **********/
SaveGame();
}
else if (menutext.equals("New Game"))
{
/* BATTLEGUI Add your code here to handle Save Game **********/
NewGame();
}
}
// Handle the event from the user clicking on a command button
else if (classname.equals("JButton"))
{
JButton button = (JButton)(e.getSource());
int bnum = Integer.parseInt(button.getActionCommand());
int row = bnum / GRID_SIZE;
int col = bnum % GRID_SIZE;
System.out.println(e.getSource());
/* BATTLEGUI Add your code here to handle user clicking on the grid ***********/
button.setBackground(Color.GREEN);
fireShot(row, col);
}
}
/**
* Returns the class name
*/
protected String getClassName(Object o)
{
String classString = o.getClass().getName();
int dotIndex = classString.lastIndexOf(".");
return classString.substring(dotIndex+1);
}
/**
* Create the GUI and show it.
* For thread safety, this method should be invoked from the event-dispatching thread.
*/
private static void createAndShowGUI()
{
// Create and set up the window.
JFrame frame = new JFrame("Battleships");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int maxGap = 20;
int ButtonWidth = 20;
int ButtonHeight = 1;
BattleGui battlegui = new BattleGui();
frame.setJMenuBar(battlegui.createMenu());
JPanel gui = new JPanel(new GridLayout(2,2,20,5));
gui.setBorder(new EmptyBorder(5,5,5,5));
//Set up components preferred size
JButton b = new JButton("Just fake button");
Dimension buttonSize = b.getPreferredSize();
gui.add(new JButton("Player"));
gui.add(new JButton("CPU"));
b.setPreferredSize(new Dimension(ButtonWidth, ButtonHeight));
gui.add(battlegui.createContentPane());
gui.add(battlegui.createContentPaneCPU());
frame.setContentPane(gui);
// Create and set up the content pane.
/*
BattleGui battlegui = new BattleGui();
frame.setJMenuBar(battlegui.createMenu());
frame.setContentPane(battlegui.createContentPane());
*/
// Display the window, setting the size
frame.setSize(800, 600);
frame.setVisible(true);
}
/**
* Sets a Gui grid square at row, col to display a character
*/
public boolean setGuiSquare(int row, int col, char c)
{
int bnum = row * GRID_SIZE + col;
if (bnum >= (GRID_SIZE*GRID_SIZE))
{
return false;
}
else
{
buttonArray[bnum].setText(Character.toString(c));
}
return true;
}
/**
* This is a standard main function for a Java GUI
*/
public static void main(String[] args)
{
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
//Deploy();
}
});
}
//************************************************************************
//*** BATTLEGUI: Modify the methods below to respond to Menu and Mouse click events
/**
* This method is called from the Menu event: New Game.
* BATTLEGUI
*/
public void NewGame()
{
System.out.println("New game selected");
}
/**
* This method is called from the Menu event: Load Game.
* BATTLEGUI
*/
public void LoadGame()
{
System.out.println("Load game selected");
}
/**
* This method is called from the Menu event: Save Game.
* BATTLEGUI
*/
public void SaveGame()
{
System.out.println("Save game selected");
}
/**
* This method is called from the Mouse Click event.
* BATTLEGUI
*/
public void fireShot(int row, int col)
{
System.out.println("Fire shot selected: at (" + row + ", " + col + ")");
}
}
I would suggest, take a step back and think about the problem domain.
You have a BattleScene, which contains BattleSquares. Each battleSquare can have atmost 1 ship, and can have a color. You also have Ship objects (which can belong to a particular player, indicates if it is damaged or not)...
BattleSquare needs to decide if it is a Hit or Miss, because it has all the information. It knows wether it has a ship or not.
/**true if had a ship, false if it was a miss
*/
public class BattleSquare{
public boolean processHit(){
if (hasShip()){
ship.setState(DESTROYED);
return true;
}
return false;
}
public void setShip(Ship ship){ .... }
public boolean hasShip() { ... } } ... methods for color too
If you isolate your code into manageable snippets, where some classes represent the model, you will be able to manage things better. You appear to be mixing everything in one class and hence are feeling lost.
Similarly, your BattleScene will contains a List of BattleSquares. Once you fire, you can individuall seek a particular BattleSquare and tell it to process itself. If it is a hit, you update the state.
Idea is that your model classes only are responsible for managing state. Your controller classes can fire events, which are intercepted by views, who update the models and refresh themselves.
hopefully it helps.

Creating context menu only for a particular item selected in the Tree Viewer

I have a TreeViewer, and I created a context menu with some actions.
With this code snippet below, I get the context menu for all tree items.
protected void createMasterPart(final IManagedForm managedForm, final Composite parent)
{
Tree t = toolkit.createTree(client, SWT.NULL);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.heightHint = 20;
gd.widthHint = 100;
t.setLayoutData(gd);
toolkit.paintBordersFor(client);
section.setClient(client);
final SectionPart spart = new SectionPart(section);
managedForm.addPart(spart);
viewer = new TreeViewer(t);
viewer.addSelectionChangedListener(new ISelectionChangedListener()
{
public void selectionChanged(SelectionChangedEvent event)
{
managedForm.fireSelectionChanged(spart, event.getSelection());
}
});
viewer.setContentProvider(new MasterTreeContentProvider());
viewer.setInput(page.getEditor().getEditorInput());
m_newKeyAction = new AddNewKeyAction(viewer, parent.getShell());
m_newValueAction = new AddNewValueAction(viewer, parent.getShell());
hookContextMenu();
}
private void hookContextMenu()
{
MenuManager menuMgr = new MenuManager();
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager)
{
fillContextMenu(manager);
}
});
Menu menu = menuMgr.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
}
protected void fillContextMenu( IMenuManager manager )
{
manager.add( m_newKeyAction );
manager.add( m_newValueAction );
}
I want this context menu to be displayed only for tree items of particular type.
Please let me know how do I get this done.

Eclipse RCP: Generating views from form values

I want to build a user interface similar to the sketch below:
When the user fills out the form on the right and clicks the 'Plot!' button, a new closeable tab opens on the left with a chart.
I am new to RCP and have been following this tutorial. I am able to bring up tabs with charts triggered from a menu item. How do I go about:
creating the tab (view?) with the form
open a new chart tab when the user clicks the button
Edit
Here is my current code. It satisfies the basic requirements outlined in this question, but I am not sure if that is the best approach. I would be delighted if someone here can guide me in the right direction.
A view with the form; the button's listener invokes a command.
public class FormView extends ViewPart {
public static final String ID =
FormView.class.getPackage().getName() + ".Form";
private FormToolkit toolkit;
private Form form;
public Text text;
#Override
public void createPartControl(Composite parent) {
toolkit = new FormToolkit(parent.getDisplay());
form = toolkit.createForm(parent);
form.setText("Pie Chucker");
GridLayout layout = new GridLayout();
form.getBody().setLayout(layout);
layout.numColumns = 2;
GridData gd = new GridData();
gd.horizontalSpan = 2;
Label label = new Label(form.getBody(), SWT.NULL);
label.setText("Chart Title:");
text = new Text(form.getBody(), SWT.BORDER);
text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Button button = new Button(form.getBody(), SWT.PUSH);
button.setText("Plot");
gd = new GridData();
gd.horizontalSpan = 2;
button.setLayoutData(gd);
button.addMouseListener(new MouseAdapter() {
#Override
public void mouseDown(MouseEvent e) {
IHandlerService handlerService = (IHandlerService) getSite()
.getService(IHandlerService.class);
try {
handlerService.executeCommand(ShowChartHandler.ID, null);
} catch (Exception ex) {
throw new RuntimeException(ShowChartHandler.ID +
" not found");
}
}
});
}
#Override
public void setFocus() {
}
}
The command invoked by the button from the form. This opens a new view with a chart.
public class ShowChartHandler extends AbstractHandler implements IHandler {
public static final String ID =
ShowChartHandler.class.getPackage().getName() + ".ShowChart";
private int count = 0;
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
try {
window.getActivePage().showView(ChartView.ID,
String.valueOf(++count), IWorkbenchPage.VIEW_ACTIVATE);
} catch (PartInitException e) {
e.printStackTrace();
}
return null;
}
}
The view with the chart. It looks up the form view and reads a value from a text field in the form (?!):
public class ChartView extends ViewPart {
public static final String ID =
ChartView.class.getPackage().getName() + ".Chart";
private static final Random random = new Random();
public ChartView() {
// TODO Auto-generated constructor stub
}
#Override
public void createPartControl(Composite parent) {
FormView form =
(FormView) Workbench.getInstance()
.getActiveWorkbenchWindow()
.getActivePage()
.findView(FormView.ID);
String title = form == null? null : form.text.getText();
if (title == null || title.trim().length() == 0) {
title = "Pie Chart";
}
setPartName(title);
JFreeChart chart = createChart(createDataset(), title);
new ChartComposite(parent, SWT.NONE, chart, true);
}
#Override
public void setFocus() {
// TODO Auto-generated method stub
}
/**
* Creates the Dataset for the Pie chart
*/
private PieDataset createDataset() {
Double[] nums = getRandomNumbers();
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("One", nums[0]);
dataset.setValue("Two", nums[1]);
dataset.setValue("Three", nums[2]);
dataset.setValue("Four", nums[3]);
dataset.setValue("Five", nums[4]);
dataset.setValue("Six", nums[5]);
return dataset;
}
private Double[] getRandomNumbers() {
Double[] nums = new Double[6];
int sum = 0;
for (int i = 0; i < 5; i++) {
int r = random.nextInt(20);
nums[i] = new Double(r);
sum += r;
}
nums[5] = new Double(100 - sum);
return nums;
}
/**
* Creates the Chart based on a dataset
*/
private JFreeChart createChart(PieDataset dataset, String title) {
JFreeChart chart = ChartFactory.createPieChart(title, // chart title
dataset, // data
true, // include legend
true, false);
PiePlot plot = (PiePlot) chart.getPlot();
plot.setSectionOutlinesVisible(false);
plot.setLabelFont(new Font("SansSerif", Font.PLAIN, 12));
plot.setNoDataMessage("No data available");
plot.setCircular(false);
plot.setLabelGap(0.02);
return chart;
}
}
The perspective that ties it all together:
public class Perspective implements IPerspectiveFactory {
public void createInitialLayout(IPageLayout layout) {
layout.setEditorAreaVisible(false);
layout.addStandaloneView(FormView.ID, false,
IPageLayout.RIGHT, 0.3f,
IPageLayout.ID_EDITOR_AREA);
IFolderLayout charts = layout.createFolder("Charts",
IPageLayout.LEFT, 0.7f, FormView.ID);
charts.addPlaceholder(ChartView.ID + ":*");
}
}
I would recommend a different aproach. Eclipse has viewparts (views) and editors. It is easy to open multiple editors. Views are not so much for open multiple ones.
So my suggestion is, that you implement the part you call "FormView" as a StandAloneView and implement the "ChartView" as an editor.
I would also recommend to use a different listener for the button, so also the code will be executed when using the keyboard to click the button.
My proposal:
public class FormView extends ViewPart {
...
button.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
// this below can also be called by a command but you need to take care about the data, which the user put into the fields in different way.
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
IWorkbenchPage page = window.getActivePage();
ChartEditorInput input = new ChartEditorInput(text.getText(),...<other data you need to pass>);
try {
page.openEditor(input, ChartEditor.ID);
} catch (PartInitException e) {
e.printStackTrace();
}
}
});
ChartView needs to be changed to ChartEditor. See here http://www.vogella.de/articles/RichClientPlatform/article.html#editor_editorinput how that is done.
ChartEditorInput hereby is a class you need to implement aside the editor class, which holds the data.
In your perspective you call:
public void createInitialLayout(IPageLayout layout) {
String editorArea = layout.getEditorArea();
layout.setFixed(false);
layout.setEditorAreaVisible(true);
layout.addStandaloneView("your.domain.and.FormView", true,IPageLayout.RIGHT, 0.15f, editorArea);
Hope this helps!

Categories