I am making a maze from a text file. The text file contains two integers on separate lines. These decide a number of rows and columns. Then the text file forms a maze by the use of '#' for walls, ' ' for passage, '*' for the players start position and '-' for the exit. When I start the program, I am able to select the file but the nodes won't align up nicely in rows and columns. Seems like they all ends up in a pile in the same place. Any tips?
package application;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javafx.application.Application;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
public class Main extends Application {
LabyrintRute[][] Labyrint;
int X;
int Y;
int startx;
int starty;
Spiller spilleren;
#Override
public void start(Stage primaryStage) {
try {
GridPane root = new GridPane();
Scene scene = new Scene(root, X*100, Y*100, Color.BLACK);
Spiller spilleren = new Spiller(startx, starty);
filLeser();
root.add(spilleren.getUtseende(), spilleren.getxPossisjon(), spilleren.getyPossisjon());
for(int x = 1; x<X; x++){
for(int y = 1; y<Y; y++){
root.add(Labyrint[x][y].getUtseende(), Labyrint[x][y].getxKoordinat(), Labyrint[x][y].getyKoordinat());
}
}
scene.setOnKeyPressed(new FilLytter(this));
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setTitle("Labyrintspill");
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public void filLeser() {
String teksten = "";
File fila;
FileChooser filvelger = new FileChooser();
filvelger.setTitle("Åpne en tekstfil");
filvelger.getExtensionFilters().add(new ExtensionFilter("Text Files", "*.txt"));
fila = filvelger.showOpenDialog(null);
try (Scanner filleser = new Scanner(fila)) {
X = filleser.nextInt();
Y = filleser.nextInt();
teksten = filleser.nextLine();
Labyrint = new LabyrintRute [X][Y];
while (filleser.hasNext()) {
teksten = filleser.nextLine();
for (int i = 1;i< X;i++) {
for (int rad = 1; rad < Y; rad++){
char tegn = teksten.charAt(i);
switch (tegn) {
case '#':
Labyrint[i][rad] = new Vegg(i, rad);
break;
case ' ':
Labyrint[i][rad] = new Gang(i, rad);
break;
case '-':
Labyrint[i][rad] = new Utgang(i, rad);
break;
case '*':
Labyrint[i][rad] = new Gang(i, rad);
startx = i;
starty = rad;
break;
}
}
}
}
} catch (FileNotFoundException e) {
System.out.println("Kan ikke åpne fila!");
e.printStackTrace();
}
}
public void flyttSpiller(int deltax, int deltay) {
int nyx = spilleren.getxPossisjon() + deltax;
int nyy = spilleren.getyPossisjon() + deltay;
Labyrint[nyx][nyy].flyttHit(spilleren);
}
public static void main(String[] args) {
launch(args);
}
}
The is the "Vegg"(wall), "Gang"(passage) and "Utgang"(exit) methods are all extensions of the "Labyrintrute" method:
package application;
import javafx.scene.Node;
public abstract class LabyrintRute {
private int xKoordinat;
private int yKoordinat;
public LabyrintRute(int xKoordinat, int yKoordinat) {
this.xKoordinat = xKoordinat;
this.yKoordinat = yKoordinat;
}
public int getxKoordinat() {
return xKoordinat;
}
public int getyKoordinat() {
return yKoordinat;
}
public abstract void flyttHit(Spiller spilleren);
public abstract Node getUtseende();
}
The "vegg"(wall), "gang"(passage) and "utgang"(exit) methods are all pretty similiar. So I'm just posting one of them:
package application;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
public class Utgang extends LabyrintRute {
private Node utseende;
public Utgang(int xKoordinat, int yKoordinat) {
super(xKoordinat, yKoordinat);
utseende = new Rectangle(10, 10, Color.BLACK);
}
#Override
public void flyttHit(Spiller spilleren) {
spilleren.setxPossisjon(getxKoordinat());
spilleren.setyPossisjon(getyKoordinat());
JFrame ramme = new JFrame();
JOptionPane.showMessageDialog(ramme, "Gratulerer! Du fant veien ut :D");
System.exit(0);
}
#Override
public Node getUtseende() {
return utseende;
}
}
Related
I have to create a Nat Table with three column and add value in the column.please help me. thanks in Advance
hope this helps. For the details of the layer you can refer the http://www.vogella.com/tutorials/NatTable/article.html link which is quite apt.
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DummyBodyDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
import org.eclipse.nebula.widgets.nattable.hideshow.ColumnHideShowLayer;
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.reorder.ColumnReorderLayer;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.Style;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Nat_explore {
private BodyLayerStack bodyLayer ;
private int statusColumn;
private int statusRejected;
private int statusInProgress;
private boolean check = false;
private NatTable nattable;
private String[] properties;
private static final String FOO_LABEL = "FOO";
private static final String CELL_LABEL = "Cell_LABEL";
public static void main(String[] args) {
new Nat_explore();
}
public Nat_explore() {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
properties = new String[3];
for(int i=0;i<properties.length;i++){
properties[i]="Column"+i;
}
//Setting the data layout layer
GridData gridData = new GridData();
gridData.heightHint = (int) 24;
gridData.widthHint = (int) 110;
IConfigRegistry configRegistry = new ConfigRegistry();
//Body Data Provider
IDataProvider dataProvider = new DataProvider(properties.length,55);
bodyLayer= new BodyLayerStack(dataProvider);
//datalayer.addConfiguration(new
//Column Data Provider
DefaultColumnHeaderDataProvider columnData = new DefaultColumnHeaderDataProvider(properties);
ColumnHeaderLayerStack columnlayer = new ColumnHeaderLayerStack(columnData);
//Row Data Provider
DefaultRowHeaderDataProvider rowdata = new DefaultRowHeaderDataProvider(dataProvider);
RowHeaderLayerStack rowlayer = new RowHeaderLayerStack(rowdata);
//Corner Data Provider
DefaultCornerDataProvider cornerdata = new DefaultCornerDataProvider(columnData, rowdata);
DataLayer cornerDataLayer = new DataLayer(cornerdata);
CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowlayer, columnlayer);
GridLayer gridlayer = new GridLayer(bodyLayer, columnlayer, rowlayer, cornerLayer);
nattable = new NatTable(shell, gridlayer,false);
// Change for paint
IConfigLabelAccumulator cellLabelAccumulator = new IConfigLabelAccumulator() {
//#Override
public void accumulateConfigLabels(LabelStack configLabels,int columnPosition, int rowPosition) {
int columnIndex = bodyLayer.getColumnIndexByPosition(columnPosition);
int rowIndex = bodyLayer.getRowIndexByPosition(rowPosition);
if (columnIndex == 2 && rowIndex == 45) {
configLabels.addLabel(FOO_LABEL);
}
else if ((columnIndex == statusColumn) && (rowIndex == statusRejected) && (check ==true)) {
configLabels.addLabel(CELL_LABEL);
}
}
};
bodyLayer.setConfigLabelAccumulator(cellLabelAccumulator);
nattable.addConfiguration(new DefaultNatTableStyleConfiguration());
nattable.addConfiguration(new AbstractRegistryConfiguration() {
//#Override
public void configureRegistry(IConfigRegistry configRegistry) {
Style cellStyle = new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR,GUIHelper.COLOR_YELLOW);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,DisplayMode.NORMAL, FOO_LABEL);
cellStyle = new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR,GUIHelper.COLOR_RED);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle,DisplayMode.NORMAL, CELL_LABEL);
}
});
nattable.setLayoutData(gridData);
nattable.setConfigRegistry(configRegistry);
nattable.configure();
shell.open();
while (!shell.isDisposed()) {
if(!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
public class DataProvider extends DummyBodyDataProvider{
public DataProvider(int columnCount, int rowCount) {
super(columnCount, rowCount);
}
#Override
public int getColumnCount() {
return properties.length;
}
#Override
public Object getDataValue(int columnIndex, int rowIndex) {
return new String("Column"+columnIndex+" Row"+rowIndex);
}
#Override
public int getRowCount() {
return 55;
}
#Override
public void setDataValue(int arg0, int arg1, Object arg2) {
}
}
public class BodyLayerStack extends AbstractLayerTransform {
private SelectionLayer selectionLayer;
public BodyLayerStack(IDataProvider dataProvider) {
DataLayer bodyDataLayer = new DataLayer(dataProvider);
ColumnReorderLayer columnReorderLayer = new ColumnReorderLayer(bodyDataLayer);
ColumnHideShowLayer columnHideShowLayer = new ColumnHideShowLayer(columnReorderLayer);
this.selectionLayer = new SelectionLayer(columnHideShowLayer);
ViewportLayer viewportLayer = new ViewportLayer(this.selectionLayer);
setUnderlyingLayer(viewportLayer);
}
public SelectionLayer getSelectionLayer() {
return this.selectionLayer;
}
}
public class ColumnHeaderLayerStack extends AbstractLayerTransform {
public ColumnHeaderLayerStack(IDataProvider dataProvider) {
DataLayer dataLayer = new DataLayer(dataProvider);
ColumnHeaderLayer colHeaderLayer = new ColumnHeaderLayer(dataLayer,Nat_explore.this.bodyLayer, Nat_explore.this.bodyLayer.getSelectionLayer());
setUnderlyingLayer(colHeaderLayer);
}
}
public class RowHeaderLayerStack extends AbstractLayerTransform {
public RowHeaderLayerStack(IDataProvider dataProvider) {
DataLayer dataLayer = new DataLayer(dataProvider, 50, 20);
RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(dataLayer,Nat_explore.this.bodyLayer, Nat_explore.this.bodyLayer.getSelectionLayer());setUnderlyingLayer(rowHeaderLayer);
}
}
}
I have put a GWT-CellTree in a DataGrid. It works except for one thing: When clicking on the tree-expand-icon, nothing happens. I have tried to minimize the
code needed to reproduce the problem...
How can this be fixed ?
best regards, Magnus
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.SimpleLayoutPanel;
public class HelloWorld implements EntryPoint {
public void onModuleLoad() {
DataGrid grid= (DataGrid) new NodesGrid().getTable();
grid.setWidth("100%");
SimpleLayoutPanel slp = new SimpleLayoutPanel();
slp.add(grid);
RootLayoutPanel.get().add(slp);
}
}
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.cell.client.ClickableTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.dom.client.Style;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.text.shared.AbstractSafeHtmlRenderer;
import com.google.gwt.text.shared.SafeHtmlRenderer;
import com.google.gwt.user.cellview.client.*;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.view.client.ListDataProvider;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
public class NodesGrid {
private AbstractCellTable<Node> table = new DataGrid<>();
private Column nameColumn;
private Column<Node, String> showBlocksColumn;
private final Set<Integer> showBlocks = new HashSet<>();
public Column getNameColumn() {
return nameColumn;
}
public AbstractCellTable<Node> getTable() {
return table;
}
public NodesGrid() {
table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
table.setWidth("100%");
CustomCellTableBuilder c = new CustomCellTableBuilder(this, table);
table.setTableBuilder(c);
Node nodes = new Node();
nodes.setName("hello");
nodes.setId(123);
Node n2 = new Node();
n2.setName("testing");
nodes.getBlocks().add(n2);
ListDataProvider<Node> dataProvider = new ListDataProvider<>();
dataProvider.addDataDisplay(table);
List<Node> list = dataProvider.getList();
list.add(nodes);
addShowBlocks();
nameColumn = getSorter(list, "Name", Comparator.comparing(Node::getName), Node::getName);
}
private Column getSorter(List<Node> list,
String name,
Comparator<Node> cmp,
Function<Node, String> supplier) {
TextColumn<Node> column = new TextColumn<Node>() {
#Override
public String getValue(Node object) {
return supplier.apply(object);
}
};
table.addColumn(column, name);
column.setSortable(true);
ColumnSortEvent.ListHandler<Node> columnSortHandler = new ColumnSortEvent.ListHandler<>(list);
columnSortHandler.setComparator(column, cmp);
table.addColumnSortHandler(columnSortHandler);
table.getColumnSortList().push(column);
return column;
}
public Column<Node, String> getShowBlocksColumn() {
return showBlocksColumn;
}
public Set<Integer> getShowBlocks() {
return showBlocks;
}
void addShowBlocks() {
SafeHtmlRenderer<String> anchorRenderer = new AbstractSafeHtmlRenderer<String>() {
#Override
public SafeHtml render(String object) {
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendHtmlConstant("(<a href=\"javascript:;\">").appendEscaped(object)
.appendHtmlConstant("</a>)");
return sb.toSafeHtml();
}
};
showBlocksColumn = new Column<Node, String>(new ClickableTextCell(anchorRenderer)) {
#Override
public String getValue(Node node) {
if (showBlocks.contains(node.getId())) {
return "hide blocks";
} else {
return "show blocks";
}
}
};
showBlocksColumn.setFieldUpdater(new FieldUpdater<Node, String>() {
#Override
public void update(int index, Node node, String value) {
if (showBlocks.contains(node.getId())) {
showBlocks.remove(node.getId());
} else {
showBlocks.add(node.getId());
}
table.redrawRow(index);
}
});
table.addColumn(showBlocksColumn);
table.setColumnWidth(0, 10, Style.Unit.EM);
}
}
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TreeNode;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.view.client.TreeViewModel;
import java.util.ArrayList;
import java.util.List;
public class NodesTree {
private CellTree tree;
public NodesTree(Node node) {
TreeViewModel model = new CustomTreeModel(node);
tree = new CellTree(model, null);
tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
TreeNode rootNode = tree.getRootTreeNode();
openAll(rootNode);
}
private static class TopLevel {
private final String name;
private List<Node> blocks = new ArrayList<>();
public TopLevel(String name) {
this.name = name;
}
public TopLevel(String name, List<Node> blocks) {
this.name = name;
this.blocks = blocks;
}
public String getName() {
return name;
}
public List<Node> getBlocks() {
return blocks;
}
}
private static class CustomTreeModel implements TreeViewModel {
private final List<TopLevel> topLevels;
private final SingleSelectionModel<String> selectionModel
= new SingleSelectionModel<>();
public CustomTreeModel(Node node) {
topLevels = new ArrayList<>();
{
TopLevel blocksNode = new TopLevel("Blocks", new ArrayList(node.getBlocks()));
topLevels.add(blocksNode);
}
{
TopLevel outgoing = new TopLevel("Outgoing");
topLevels.add(outgoing);
}
{
TopLevel incoming = new TopLevel("Incoming");
topLevels.add(incoming);
}
}
public <T> NodeInfo<?> getNodeInfo(T value) {
if (value == null) {
// LEVEL 0.
ListDataProvider<TopLevel> dataProvider
= new ListDataProvider<>(
topLevels);
Cell<TopLevel> cell = new AbstractCell<TopLevel>() {
#Override
public void render(Context context, TopLevel value, SafeHtmlBuilder sb) {
sb.appendHtmlConstant(" ");
sb.appendEscaped(value.getName());
}
};
return new DefaultNodeInfo<>(dataProvider, cell);
} else if (value instanceof TopLevel) {
// LEVEL 1.
ListDataProvider<Node> dataProvider = new ListDataProvider<>(((TopLevel) value).getBlocks());
Cell<Node> cell = new AbstractCell<Node>() {
#Override
public void render(Context context, Node value, SafeHtmlBuilder sb) {
if (value != null) {
sb.appendHtmlConstant(" ");
sb.appendEscaped("(" + value.getName() + ")");
}
}
};
return new DefaultNodeInfo<>(dataProvider, cell);
} else if (value instanceof Node) {
// LEVEL 2 - LEAF.
String params = "test";
ArrayList<String> str = new ArrayList<>();
str.add(params);
ListDataProvider<String> dataProvider = new ListDataProvider<>(str);
return new DefaultNodeInfo<>(dataProvider, new TextCell(), selectionModel, null);
}
return null;
}
public boolean isLeaf(Object value) {
if (value instanceof String) {
return true;
}
return false;
}
}
private void openAll(TreeNode rootNode) {
if (rootNode == null) return;
for (int i = 0; i < rootNode.getChildCount(); i++) {
TreeNode node = rootNode.setChildOpen(i, true);
openAll(node);
}
}
public Widget getWidget() {
return tree;
}
}
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.dom.builder.shared.DivBuilder;
import com.google.gwt.dom.builder.shared.TableCellBuilder;
import com.google.gwt.dom.builder.shared.TableRowBuilder;
import com.google.gwt.dom.client.Style;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.cellview.client.AbstractCellTable;
import com.google.gwt.user.cellview.client.AbstractCellTableBuilder;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.view.client.SelectionModel;
public class CustomCellTableBuilder extends AbstractCellTableBuilder<Node> {
NodesGrid nodesGrid;
private final String rowStyle;
private final String selectedRowStyle;
private final String cellStyle;
private final String selectedCellStyle;
/**
* Construct a new table builder.
*
* #param cellTable the table this builder will build rows for
*/
public CustomCellTableBuilder(NodesGrid nodesGrid, AbstractCellTable<Node> cellTable) {
super(cellTable);
this.nodesGrid = nodesGrid;
AbstractCellTable.Style style = cellTable.getResources().style();
rowStyle = style.evenRow();
selectedRowStyle = " " + style.selectedRow();
cellStyle = style.cell() + " " + style.evenRowCell();
selectedCellStyle = " " + style.selectedRowCell();
}
#Override
protected void buildRowImpl(Node rowValue, int absRowIndex) {
// Calculate the row styles.
SelectionModel<? super Node> selectionModel = cellTable.getSelectionModel();
boolean isSelected =
(selectionModel == null || rowValue == null) ? false : selectionModel
.isSelected(rowValue);
StringBuilder trClasses = new StringBuilder(rowStyle);
if (isSelected) {
trClasses.append(selectedRowStyle);
}
String cellStyles = cellStyle;
if (isSelected) {
cellStyles += selectedCellStyle;
}
TableRowBuilder row = startRow();
row.className(trClasses.toString());
buildRow(row, rowValue, cellStyles, nodesGrid.getShowBlocksColumn());
buildRow(row, rowValue, cellStyles, nodesGrid.getNameColumn());
row.endTR();
if (nodesGrid.getShowBlocks().contains(rowValue.getId())) {
buildBlockRow(rowValue, cellStyles);
}
}
void buildRow(TableRowBuilder row, Node rowValue, String cellStyles, Column column) {
TableCellBuilder td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(Style.OutlineStyle.NONE).endStyle();
renderCell(td, createContext(0), column, rowValue);
td.endTD();
}
private void buildBlockRow(Node rowValue, String cellStyles) {
TableRowBuilder row = startRow();
buildCell(rowValue, cellStyles, row);
row.endTR();
}
private void buildCell(Node rowValue, String cellStyles, TableRowBuilder row) {
NodesTree hw = new NodesTree(rowValue);
TableCellBuilder td = row.startTD().colSpan(5);
td.className(cellStyles);
DivBuilder div = td.startDiv();
String t = hw.getWidget().getElement().getInnerHTML();
div.html(SafeHtmlUtils.fromTrustedString(t));
div.end();
td.endTD();
}
}
package com.raybased.gwt.configtool.client.grid;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class Node implements Serializable {
String name;
List<Node> blocks = new ArrayList<>();
String params;
int id;
public Node() {
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Node> getBlocks() {
return blocks;
}
}
I want to add Tooltip when I move cursor over a chart line. I found this example:
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
public class AnimatedLineChart extends Application {
private static final int MAX_DATA_POINTS = 50;
private int xSeriesData = 0;
private XYChart.Series series1;
private XYChart.Series series2;
private XYChart.Series series3;
private ExecutorService executor;
private AddToQueue addToQueue;
private ConcurrentLinkedQueue<Number> dataQ1 = new ConcurrentLinkedQueue<Number>();
private ConcurrentLinkedQueue<Number> dataQ2 = new ConcurrentLinkedQueue<Number>();
private ConcurrentLinkedQueue<Number> dataQ3 = new ConcurrentLinkedQueue<Number>();
private NumberAxis xAxis;
private void init(Stage primaryStage) {
xAxis = new NumberAxis(0,MAX_DATA_POINTS,MAX_DATA_POINTS/10);
xAxis.setForceZeroInRange(false);
xAxis.setAutoRanging(false);
xAxis.setTickLabelsVisible(false);
xAxis.setTickMarkVisible(false);
xAxis.setMinorTickVisible(false);
NumberAxis yAxis = new NumberAxis();
yAxis.setAutoRanging(true);
//-- Chart
final LineChart<Number, Number> sc = new LineChart<Number, Number>(xAxis, yAxis) {
// Override to remove symbols on each data point
#Override protected void dataItemAdded(Series<Number, Number> series, int itemIndex, Data<Number, Number> item) {}
};
sc.setAnimated(false);
sc.setId("liveLineeChart");
sc.setTitle("Animated Line Chart");
//-- Chart Series
series1 = new XYChart.Series<Number, Number>();
series2 = new XYChart.Series<Number, Number>();
series3 = new XYChart.Series<Number, Number>();
sc.getData().addAll(series1, series2, series3);
primaryStage.setScene(new Scene(sc));
}
#Override public void start(Stage stage) {
stage.setTitle("Animated Line Chart Sample");
init(stage);
stage.show();
executor = Executors.newCachedThreadPool(new ThreadFactory() {
#Override public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
addToQueue = new AddToQueue();
executor.execute(addToQueue);
//-- Prepare Timeline
prepareTimeline();
}
private class AddToQueue implements Runnable {
public void run() {
try {
// add a item of random data to queue
dataQ1.add(Math.random());
dataQ2.add(Math.random());
dataQ3.add(Math.random());
Thread.sleep(500);
executor.execute(this);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
//-- Timeline gets called in the JavaFX Main thread
private void prepareTimeline() {
// Every frame to take any data from queue and add to chart
new AnimationTimer() {
#Override public void handle(long now) {
addDataToSeries();
}
}.start();
}
private void addDataToSeries() {
for (int i = 0; i < 20; i++) { //-- add 20 numbers to the plot+
if (dataQ1.isEmpty()) break;
series1.getData().add(new AreaChart.Data(xSeriesData++, dataQ1.remove()));
series2.getData().add(new AreaChart.Data(xSeriesData++, dataQ2.remove()));
series3.getData().add(new AreaChart.Data(xSeriesData++, dataQ3.remove()));
}
// remove points to keep us at no more than MAX_DATA_POINTS
if (series1.getData().size() > MAX_DATA_POINTS) {
series1.getData().remove(0, series1.getData().size() - MAX_DATA_POINTS);
}
if (series2.getData().size() > MAX_DATA_POINTS) {
series2.getData().remove(0, series2.getData().size() - MAX_DATA_POINTS);
}
if (series3.getData().size() > MAX_DATA_POINTS) {
series3.getData().remove(0, series3.getData().size() - MAX_DATA_POINTS);
}
// update
xAxis.setLowerBound(xSeriesData-MAX_DATA_POINTS);
xAxis.setUpperBound(xSeriesData-1);
}
public static void main(String[] args) {
launch(args);
}
}
For example I would like to display something like this:
Is this possible with JavaFX 8? On mouse hover it is showing Date.
Is there any similar example that I can use for my case?
I have managed to pull something very close to what you want. Have a look at the image below
I have used DateAxis for populating date on X-axis, along with events on Y-axis. Once the data is populated in the LineChart, iterate through its data and apply a tooltip on each node.
I have also used a styleclass on mouseEntered to apply the effect as shown on the image. This styleclass is removed on mouseExit
Have a look at the code below :
ToolTipOnLineChart.java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Tooltip;
import javafx.stage.Stage;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ToolTipOnLineChart extends Application {
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public void start(Stage stage) throws ParseException {
stage.setTitle("Line Chart Sample");
final DateAxis xAxis = new DateAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Date");
yAxis.setLabel("Events");
final LineChart<Date,Number> lineChart = new LineChart<>(xAxis, yAxis);
lineChart.setTitle("Events");
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MMM/yyyy");
XYChart.Series<Date,Number> series = new XYChart.Series<>();
series.setName("Events this Year");
series.getData().add(new XYChart.Data(dateFormat.parse("11/Jan/2014"), 23));
series.getData().add(new XYChart.Data(dateFormat.parse("09/Feb/2014"), 14));
series.getData().add(new XYChart.Data(dateFormat.parse("22/Mar/2014"), 15));
series.getData().add(new XYChart.Data(dateFormat.parse("14/Apr/2014"), 24));
series.getData().add(new XYChart.Data(dateFormat.parse("22/May/2014"), 34));
series.getData().add(new XYChart.Data(dateFormat.parse("07/Jun/2014"), 36));
series.getData().add(new XYChart.Data(dateFormat.parse("22/Jul/2014"), 22));
series.getData().add(new XYChart.Data(dateFormat.parse("21/Aug/2014"), 45));
series.getData().add(new XYChart.Data(dateFormat.parse("04/Sep/2014"), 43));
series.getData().add(new XYChart.Data(dateFormat.parse("22/Oct/2014"), 17));
series.getData().add(new XYChart.Data(dateFormat.parse("30/Nov/2014"), 29));
series.getData().add(new XYChart.Data(dateFormat.parse("10/Dec/2014"), 25));
Scene scene = new Scene(lineChart,800,600);
scene.getStylesheets().add(getClass().getResource("chart.css").toExternalForm());
lineChart.getData().add(series);
stage.setScene(scene);
stage.show();
/**
* Browsing through the Data and applying ToolTip
* as well as the class on hover
*/
for (XYChart.Series<Date, Number> s : lineChart.getData()) {
for (XYChart.Data<Date, Number> d : s.getData()) {
Tooltip.install(d.getNode(), new Tooltip(
d.getXValue().toString() + "\n" +
"Number Of Events : " + d.getYValue()));
//Adding class on hover
d.getNode().setOnMouseEntered(event -> d.getNode().getStyleClass().add("onHover"));
//Removing class on exit
d.getNode().setOnMouseExited(event -> d.getNode().getStyleClass().remove("onHover"));
}
}
}
public static void main(String[] args) {
launch(args);
}
}
chart.css
.onHover{
-fx-background-color: ORANGE;
}
I have a test application that I draw a Polygon using google maps API.
The problem is that, when I have no cache of any maps (new installed application) the Polygon does not draw.
Its not a problem not having the maps loaded, but I do need the Polygons drawn in my screen.
Is there a way I can do that?
Sry for my bad english
Heres the code I have:
package ngvl.testegmaps_v2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import ngvl.testegmaps_v2.VO.GeoPosicionamento;
import ngvl.testegmaps_v2.VO.Layer;
import ngvl.testegmaps_v2.VO.Secao;
import ngvl.testegmaps_v2.VO.Talhao;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class MainActivity extends FragmentActivity {
private List<Secao> secoes;
private List<Polygon> poligonos = new ArrayList<Polygon>();
private HashMap<String,Object[]> informacoes = new HashMap<String,Object[]>();
private GoogleMap map;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
map = fragment.getMap();
map.getUiSettings().setRotateGesturesEnabled(false);
// Setting a click event handler for the map
LatLng latLng = new LatLng(-20.9957152, -47.3241304);
// map.addMarker(new
// MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)).title("Av. Paulista").snippet("São Paulo"));
configuraPosicao(map, latLng);
Button button = (Button)findViewById(R.id.button1);
// Register the onClick listener with the implementation above
button.setOnClickListener(mCorkyListener);
}
private void configuraPosicao(GoogleMap map, LatLng latLng) {
/*
* 3D map.moveCamera( CameraUpdateFactory.newLatLngZoom(latLng, 15));
* map.animateCamera( CameraUpdateFactory.zoomTo(10), 2000, null);
*
* CameraPosition cameraPosition = new CameraPosition.Builder()
* .target(latLng) .zoom(17) .bearing(90) .tilt(45) .build();
*
* map.animateCamera( CameraUpdateFactory.newCameraPosition(
* cameraPosition));
*/
map.setMapType(GoogleMap.MAP_TYPE_NONE);
// map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17.0f));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
try {
String json = readFileAsString("geo.json");
Gson gson = new Gson();
this.secoes = gson.fromJson(json, new TypeToken<List<Secao>>() {
}.getType());
json = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
escrevePoligons(map);
}
private String readFileAsString(String fileName) throws IOException {
InputStream is = getAssets().open(fileName);
if (is != null) {
StringBuilder sb = new StringBuilder();
String line;
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "UTF-8"));
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
} finally {
is.close();
}
return sb.toString();
} else {
return "";
}
}
private void escrevePoligons(GoogleMap map) {
float stroke = (float) 1.5;
for (Secao secao : secoes) {
for (Talhao talhao : secao.getTalhoes()) {
for (Layer layer : talhao.getLayers()) {
// PolygonOptions rectOptions = new PolygonOptions();
List<LatLng> latlngs = new ArrayList<LatLng>();
for (GeoPosicionamento geoPosicionamento : layer.getGeoPosicionamentos()) {
latlngs.add(new LatLng(geoPosicionamento.getLatitude()
.setScale(7, BigDecimal.ROUND_HALF_EVEN)
.doubleValue(), geoPosicionamento
.getLongitude()
.setScale(7, BigDecimal.ROUND_HALF_EVEN)
.doubleValue()));
}
int color = 0x1F00FF00;
int color2 = 0x5F000000;
PolygonOptions polygonOptions = new PolygonOptions()
.fillColor(color).addAll(latlngs)
.strokeColor(color2).strokeWidth(stroke);
Polygon p = map.addPolygon(polygonOptions);
poligonos.add(p);
informacoes.put( p.getId(), new Object[]{ secao, talhao , layer } );
//System.out.println(polygonOptions.getPoints());
polygonOptions = null;
latlngs = null;
}
}
}
this.secoes = null;
// String mUrl =
// "https://khms0.google.com.br/kh/v=124&src=app&z={z}&x={x}&y={y}";
// MyUrlTileProvider mTileProvider = new MyUrlTileProvider(256, 256,
// mUrl);
// mTileProvider.tilesRange();
// map.addTileOverlay(new
// TileOverlayOptions().tileProvider(mTileProvider).zIndex(-1f));
//String mUrl = "http://a.tile.openstreetmap.org/{z}/{x}/{y}.png";
//MyUrlTileProvider mTileProvider = new MyUrlTileProvider(256, 256, mUrl);
//map.addTileOverlay(new TileOverlayOptions().tileProvider(mTileProvider).zIndex(-1f));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-20.9957152, -47.3241304), 14));
// TileProvider tileProvider = TileProviderFactory.getTileProvider();
// map.addTileOverlay(new
// TileOverlayOptions().tileProvider(tileProvider));
// map.moveCamera(CameraUpdateFactory.newLatLngZoom(new
// LatLng(-20.9957152, -47.3241304), 15));
map.setOnMapClickListener(new OnMapClickListener()
{
public void onMapClick(LatLng point)
{
Polygon p = isPointInPolygon(point);
if( p != null){
p.setFillColor(getRandomColor());
Object[] clicado = informacoes.get( p.getId() );
Secao secao_clicada = (Secao) clicado[0];
Talhao talhao_clicada = (Talhao) clicado[1];
Layer layer_clicada = (Layer) clicado[2];
//System.out.println(secao_clicada);
//System.out.println(talhao_clicada);
//System.out.println(layer_clicada);
//System.out.println("=======================");
StringBuilder texto = new StringBuilder();
texto.append("Seção: " + secao_clicada.getDesc() + "\n");
texto.append("Talhão: " + talhao_clicada.getTalhao() + "\n");
texto.append("Variedade: " + talhao_clicada.getVariedade() + " - " + talhao_clicada.getDescVariedade() + "\n");
texto.append("Layer: " + layer_clicada.getSequencia() + "\n");
//Toast.makeText(MainActivity.this, texto , Toast.LENGTH_LONG).show();
addMarker(point,texto);
}//else
//Toast.makeText(MainActivity.this,"Clicou fora da Área de um Poligono", Toast.LENGTH_LONG).show();
}
});
}
public void addMarker(LatLng point, StringBuilder texto) {
/*map.addMarker(new MarkerOptions().position(point).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))
.title("Caracteristicas: ")
.snippet( texto );
*/
Toast.makeText(MainActivity.this, texto , Toast.LENGTH_LONG).show();
}
private Polygon isPointInPolygon(LatLng tap) {
for( Polygon p : poligonos){
int intersectCount = 0;
List<LatLng> vertices = p.getPoints();
for(int j=0; j<vertices.size()-1; j++) {
if( rayCastIntersect(tap, vertices.get(j), vertices.get(j+1)) ) {
intersectCount++;
}
}
if(((intersectCount % 2) == 1)){
return p;
}
}
return null;// odd = inside, even = outside;
}
private boolean rayCastIntersect(LatLng tap, LatLng vertA, LatLng vertB) {
double aY = vertA.latitude;
double bY = vertB.latitude;
double aX = vertA.longitude;
double bX = vertB.longitude;
double pY = tap.latitude;
double pX = tap.longitude;
if ( (aY>pY && bY>pY) || (aY<pY && bY<pY) || (aX<pX && bX<pX) ) {
return false; // a and b can't both be above or below pt.y, and a or b must be east of pt.x
}
double m = (aY-bY) / (aX-bX); // Rise over run
double bee = (-aX) * m + aY; // y = mx + b
double x = (pY - bee) / m; // algebra is neat!
return x > pX;
}
private OnClickListener mCorkyListener = new OnClickListener() {
public void onClick(View v) {
// do something when the button is clicked
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-20.9957152, -47.3241304), 14));
}
};
public int getRandomColor() {
int color;
Random rnd = new Random();
color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256),
rnd.nextInt(256));
return color;
}
}
Setting map type to MAP_TYPE_NONE like example above does not solve the problem
I will this as marked solved by using Maps Forge Open Source API
If someone did with Google Maps Api please share and I would change the answer.
The answer I found is that its impossible to render or access anything without rendering the map first (online or via cache)
This is actually a bug of GoogleMaps Api v2 for Android.
It is referenced here:
https://code.google.com/p/gmaps-api-issues/issues/detail?id=5017
Star it if you want to accelerate the bug fix!
I want a customized StyledText widget which can accept a keyword list,then highlight these keywords!
I found it's very hard to implement it by myself.
God damned! after spent hours searching the web, I finally found some sample code from the book The Definitive Guide to SWT and JFace, it's quite simple :
Main class :
package amarsoft.rcp.base.widgets.test;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import amarsoft.rcp.base.widgets.SQLSegmentEditor;
public class PageDemo extends ApplicationWindow {
public PageDemo(Shell parentShell) {
super(parentShell);
final Composite topComp = new Composite(parentShell, SWT.BORDER);
FillLayout fl = new FillLayout();
fl.marginWidth = 100;
topComp.setLayout(fl);
new SQLSegmentEditor(topComp);
}
/**
* #param args
*/
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
new PageDemo(shell);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
package amarsoft.rcp.base.widgets;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
/**
* SQL语句/SQL语句片段编辑器,除了内容编辑之外,提供一个额外的功能——常用SQL语句关键字高亮显示。
* #author ggfan#amarsoft
*
*/
public class SQLSegmentEditor extends Composite{
private StyledText st;
public SQLSegmentEditor(Composite parent) {
super(parent, SWT.NONE);
this.setLayout(new FillLayout());
st = new StyledText(this, SWT.WRAP);
st.addLineStyleListener(new SQLSegmentLineStyleListener());
}
}
package amarsoft.rcp.base.widgets;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.LineStyleEvent;
import org.eclipse.swt.custom.LineStyleListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.wb.swt.SWTResourceManager;
public class SQLSegmentLineStyleListener implements LineStyleListener {
private static final Color KEYWORD_COLOR = SWTResourceManager
.getColor(SWT.COLOR_BLUE);
private List<String> keywords = new ArrayList<String>();
public SQLSegmentLineStyleListener() {
super();
keywords.add("select");
keywords.add("from");
keywords.add("where");
}
#Override
public void lineGetStyle(LineStyleEvent event) {
List<StyleRange> styles = new ArrayList<StyleRange>();
int start = 0;
int length = event.lineText.length();
System.out.println("current line length:" + event.lineText.length());
while (start < length) {
System.out.println("while lopp");
if (Character.isLetter(event.lineText.charAt(start))) {
StringBuffer buf = new StringBuffer();
int i = start;
for (; i < length
&& Character.isLetter(event.lineText.charAt(i)); i++) {
buf.append(event.lineText.charAt(i));
}
if (keywords.contains(buf.toString())) {
styles.add(new StyleRange(event.lineOffset + start, i - start, KEYWORD_COLOR, null, SWT.BOLD));
}
start = i;
}
else{
start ++;
}
}
event.styles = (StyleRange[]) styles.toArray(new StyleRange[0]);
}
}