When I create a ScatterChart I always have this redundant blank space on the left and bottom and I want to remove it.
Here is my piece of code. xAxis.autosize() and yAxis.autosize() don't change anything.
vbox {
add(ScatterChart(NumberAxis(), NumberAxis()).apply {
val seriesMap: HashMap<String, XYChart.Series<Number, Number>> = HashMap()
pointsList
.map { it.decisionClass }
.distinct()
.forEach {
seriesMap.put(it, XYChart.Series())
}
for (point in pointsList) {
seriesMap.get(point.decisionClass)?.data(point.axisesValues[0], point.axisesValues[1])
}
seriesMap
.toSortedMap()
.forEach { key, value ->
value.name = key
data.add(value)
}
xAxis.autosize()
yAxis.autosize()
})
}
How to autosize a series?
Thanks to #James_D I ended up with this piece of code.
vbox {
add(ScatterChart(NumberAxis(), NumberAxis()).apply {
val seriesMap: HashMap<String, XYChart.Series<Number, Number>> = HashMap()
pointsList
.map { it.decisionClass }
.distinct()
.forEach {
seriesMap.put(it, XYChart.Series())
}
for (point in pointsList) {
seriesMap.get(point.decisionClass)?.data(point.axisesValues[0], point.axisesValues[1])
}
seriesMap
.toSortedMap()
.forEach { key, value ->
value.name = key
data.add(value)
}
(xAxis as NumberAxis).setForceZeroInRange(false)
(yAxis as NumberAxis).setForceZeroInRange(false)
})
}
Related
I want to show the weight of an edge when the mouse hovers over it.
So I use an MouseEvent.MOUSE_MOVED in my implemented MouseManager. With nodes, I just can call view.findGraphicElementAt(getManagedTypes(), event.getX(), event.getY()) to get the GraphicNode Object. Unfortunately, edges do not have one x and y value, and are thus not found by this method. Yes, I know getX()and getY() are implemented for a GraphicEdge but are just pointing at the center of the edge.
I need the Edge Object to get some further information stored at the edge (like weight). So how do I get the Edge Object using x,y or some other values I can retrieve from the received MouseEvent?
In fact, edge selection, mouseOver, and mouseLeft functions (which kind of includes hovering over edges) is already implemented in the MouseOverMouseManager or FxMouseOverMouseManager. This manager is automatically set when calling view.enableMouseOptions() but I already implemented an individual MouseManager for some other reasons plus hovering over an edge is only detected when hovering over the center of the edge. So my solution was to copy the code from MouseOverMouseManager into MyMousemanager and modify it.
Edit:
public class CompoundListNetworkMouseManager extends FxMouseManager {
private GraphicElement hoveredElement;
private long hoveredElementLastChanged;
private ReentrantLock hoverLock = new ReentrantLock();
private Timer hoverTimer = new Timer(true);
private HoverTimerTask latestHoverTimerTask;
/**
*(copied from the GraphsStream Library)
* The mouse needs to stay on an element for at least this amount of milliseconds,
* until the element gets the attribute "ui.mouseOver" assigned.
* A value smaller or equal to zero indicates, that the attribute is assigned without delay.
* */
private final long delayHover;
public CompoundListNetworkMouseManager(){
super(EnumSet.of(InteractiveElement.NODE, InteractiveElement.EDGE));
this.delayHover = 100;
}
#Override
public void init(GraphicGraph graph, View view) {
this.graph = graph;
this.view = view;
view.addListener(MouseEvent.MOUSE_MOVED, mouseMoved);
}
#Override
public void release() {
view.removeListener(MouseEvent.MOUSE_MOVED, mouseMoved);
}
#Override
public EnumSet<InteractiveElement> getManagedTypes() {
return super.getManagedTypes();
}
protected void mouseOverElement(GraphicElement element){
element.setAttribute("ui.mouseOver", true);
element.setAttribute("ui.class", "mouseOver"); //I defined a class/type for edges in the CSS styling sheet that is calles "mouseOver"
if(element instanceof GraphicEdge) {
mouseOverEdge((GraphicEdge) element);
}
else if(element instanceof GraphicNode){
mouseOverNode((GraphicNode) element);
}
protected void mouseOverEdge(GraphicEdge graphicEdge) {
view.freezeElement(graphicEdge, true);
Edge edge = graph.getEdge(graphicEdge.getId());
System.out.println("Mouse over edge " + edge.getId());
}
protected void mouseLeftElement(GraphicElement element) {
this.hoveredElement = null;
element.removeAttribute("ui.mouseOver");
element.removeAttribute("ui.class");
}
EventHandler<MouseEvent> mouseMoved = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
try {
hoverLock.lockInterruptibly();
boolean stayedOnElement = false;
curElement = view.findGraphicElementAt(getManagedTypes(), event.getX(), event.getY());
//adjusted implementation of search for edges
if(curElement == null && getManagedTypes().contains(InteractiveElement.EDGE)){
curElement = (GraphicElement) findEdgeAt(event.getX(), event.getY());
}
if(hoveredElement != null) {
//check if mouse stayed on the same element to avoid the mouseOverEvent being processed multiple times
stayedOnElement = curElement == null ? false : curElement.equals(hoveredElement);
if (!stayedOnElement && hoveredElement.hasAttribute("ui.mouseOver")) {
mouseLeftElement(hoveredElement);
}
}
if (!stayedOnElement && curElement != null) {
if (delayHover <= 0) {
mouseOverElement(curElement);
} else {
hoveredElement = curElement;
hoveredElementLastChanged = Calendar.getInstance().getTimeInMillis();
if (latestHoverTimerTask != null) {
latestHoverTimerTask.cancel();
}
latestHoverTimerTask = new HoverTimerTask(hoveredElementLastChanged, hoveredElement);
hoverTimer.schedule(latestHoverTimerTask, delayHover);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
hoverLock.unlock();
}
}
};
//copied from GraphStream Library
private final class HoverTimerTask extends TimerTask {
private final long lastChanged;
private final GraphicElement element;
public HoverTimerTask(long lastChanged, GraphicElement element) {
this.lastChanged = lastChanged;
this.element = element;
}
#Override
public void run() {
try {
hoverLock.lock();
if (hoveredElementLastChanged == lastChanged) {
mouseOverElement(element);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
hoverLock.unlock();
}
}
}
//findGraphicElement could be used but I wanted to implement the edgeContains method myself
private Edge findEdgeAt(double x, double y){
Camera cam = view.getCamera();
GraphMetrics metrics = cam.getMetrics();
//transform x and y
double xT = x + metrics.viewport[0];
double yT = y + metrics.viewport[0];
Edge edgeFound = null;
if (getManagedTypes().contains(InteractiveElement.EDGE)) {
Optional<Edge> edge = graph.edges().filter(e -> edgeContains((GraphicEdge) e, xT, yT)).findFirst();
if (edge.isPresent()) {
if (cam.isVisible((GraphicElement) edge.get())) {
edgeFound = edge.get();
}
}
}
return edgeFound;
}
//new edgeContains() method that finds edge at hovering not only when hovered over edge center
private boolean edgeContains(GraphicEdge edge, double x, double y) {
Camera cam = view.getCamera();
GraphMetrics metrics = cam.getMetrics();
Values size = edge.getStyle().getSize();
double deviation = metrics.lengthToPx(size, 0);
Point3 edgeNode0 = cam.transformGuToPx(edge.from.x, edge.from.y, 0);
Point3 edgeNode1 = cam.transformGuToPx(edge.to.x, edge.to.y, 0);
//check of point x,y is between nodes of the edge
boolean edgeContains = false;
//check x,y range
if(x > Math.min(edgeNode0.x, edgeNode1.x) - deviation
&& x < Math.max(edgeNode0.x, edgeNode1.x) + deviation
&& y > Math.min(edgeNode0.y, edgeNode1.y) - deviation
&& y < Math.max(edgeNode0.y, edgeNode1.y) + deviation){
//check deviation from edge
Vector2 vectorNode0To1 = new Vector2(edgeNode0, edgeNode1);
Point2 point = new Point2(x, y);
Vector2 vectorNode0ToPoint = new Vector2(edgeNode0, point);
//cross product of vectorNode0ToPoint and vectorNode0to1
double crossProduct = vectorNode0ToPoint.x() * vectorNode0To1.y() - vectorNode0To1.x() * vectorNode0ToPoint.y();
//distance of point to the line extending the edge
double d = Math.abs(crossProduct) / vectorNode0To1.length();
if(d <= deviation){
edgeContains = true;
}
}
return edgeContains;
}
}
CSS Stylesheet:
...
edge{
fill-color: black;
size: 2px;
arrow-shape: none;
shape: line;
text-mode: hidden;
}
edge.mouseOver {
fill-color: red;
stroke-color: red;
text-mode: normal;
text-background-mode: plain; /*plain or none*/
text-background-color: rgba(255, 255, 255, 200);
text-alignment: along;
}
I am very new using Kotlin and programming and I am currently making a calendar with events. My problem comes when I want to connect these events to firebase.
I am using an example that I found in git (https://github.com/kizitonwose/CalendarView) that uses the ThreeTen library for dates. This is the Event object:
class Event (val id: String, val text: String, val date: LocalDate) : Serializable
The data variable is of the LocalData type and this is what is causing me problems since it seems that Firebase only accepts variables of type String, Int, etc ...
I tried to pass the variable to String with toString and with Gson (), without success.
Here is the code if it helps
private val inputDialog by lazy {
val editText = AppCompatEditText(requireContext())
val layout = FrameLayout(requireContext()).apply {
// Setting the padding on the EditText only pads the input area
// not the entire EditText so we wrap it in a FrameLayout.
setPadding(20, 20, 20, 20)
addView(editText, FrameLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT))
}
AlertDialog.Builder(requireContext())
.setTitle(getString(R.string.example_3_input_dialog_title))
.setView(layout)
.setPositiveButton(R.string.save) { _, _ ->
saveEvent(editText.text.toString())
// Prepare EditText for reuse.
editText.setText("")
}
.setNegativeButton(R.string.close, null)
.create()
.apply {
setOnShowListener {
// Show the keyboard
editText.requestFocus()
context.inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
}
setOnDismissListener {
// Hide the keyboard
context.inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
}
}
}
private var selectedDate: LocalDate? = null
private val today = LocalDate.now()
private val titleSameYearFormatter = DateTimeFormatter.ofPattern("MMMM")
private val titleFormatter = DateTimeFormatter.ofPattern("MMM yyyy")
private val selectionFormatter = DateTimeFormatter.ofPattern("yyyy MM dd")
private val events = mutableMapOf<LocalDate, List<Event>>()
private var prueba = Gson().toJson(events)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_calendar, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mDatabaseReference = mDatabase!!.reference.child("events")
exThreeRv.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
exThreeRv.adapter = eventsAdapter
exThreeRv.addItemDecoration(DividerItemDecoration(requireContext(), RecyclerView.VERTICAL))
val daysOfWeek = daysOfWeekFromLocale()
val currentMonth = YearMonth.now()
exThreeCalendar.setup(currentMonth.minusMonths(10), currentMonth.plusMonths(10), daysOfWeek.first())
exThreeCalendar.scrollToMonth(currentMonth)
if (savedInstanceState == null) {
exThreeCalendar.post {
// Show today's events initially.
selectDate(today)
}
}
class DayViewContainer(view: View) : ViewContainer(view) {
lateinit var day: CalendarDay // Will be set when this container is bound.
val textView = view.exThreeDayText
val dotView = view.exThreeDotView
init {
view.setOnClickListener {
if (day.owner == DayOwner.THIS_MONTH) {
selectDate(day.date)
}
}
}
}
exThreeCalendar.dayBinder = object : DayBinder<DayViewContainer> {
override fun create(view: View) = DayViewContainer(view)
override fun bind(container: DayViewContainer, day: CalendarDay) {
container.day = day
val textView = container.textView
val dotView = container.dotView
textView.text = day.date.dayOfMonth.toString()
if (day.owner == DayOwner.THIS_MONTH) {
textView.makeVisible()
when (day.date) {
today -> {
textView.setTextColorRes(R.color.white)
textView.setBackgroundResource(R.drawable.today_bg)
dotView.makeInVisible()
}
selectedDate -> {
textView.setTextColorRes(R.color.white)
textView.setBackgroundResource(R.drawable.selected_bg)
dotView.makeInVisible()
}
else -> {
textView.setTextColorRes(R.color.black)
textView.background = null
dotView.isVisible = events[day.date].orEmpty().isNotEmpty()
}
}
} else {
textView.makeInVisible()
dotView.makeInVisible()
}
}
}
exThreeCalendar.monthScrollListener = {
requireActivity().home.text = if (it.year == today.year) {
titleSameYearFormatter.format(it.yearMonth)
} else {
titleFormatter.format(it.yearMonth)
}
// Select the first day of the month when
// we scroll to a new month.
selectDate(it.yearMonth.atDay(1))
}
class MonthViewContainer(view: View) : ViewContainer(view) {
val legendLayout = view.legendLayout
}
exThreeCalendar.monthHeaderBinder = object : MonthHeaderFooterBinder<MonthViewContainer> {
override fun create(view: View) = MonthViewContainer(view)
override fun bind(container: MonthViewContainer, month: CalendarMonth) {
// Setup each header day text if we have not done that already.
if (container.legendLayout.tag == null) {
container.legendLayout.tag = month.yearMonth
container.legendLayout.children.map { it as TextView }.forEachIndexed { index, tv ->
tv.text = daysOfWeek[index].name.first().toString()
tv.setTextColorRes(R.color.black)
}
}
}
}
exThreeAddButton.setOnClickListener {
inputDialog.show()
}
}
private fun selectDate(date: LocalDate) {
if (selectedDate != date) {
val oldDate = selectedDate
selectedDate = date
oldDate?.let { exThreeCalendar.notifyDateChanged(it) }
exThreeCalendar.notifyDateChanged(date)
updateAdapterForDate(date)
}
}
private fun saveEvent(text: String) {
if (text.isBlank()) {
Toast.makeText(requireContext(),
R.string.example_3_empty_input_text, Toast.LENGTH_LONG).show()
} else {
selectedDate?.let {
events[it] = events[it].orEmpty().plus(
Event(
UUID.randomUUID().toString(),
text,
it
)
)
uploadFirebase()
updateAdapterForDate(it)
}
}
}
private fun deleteEvent(event: Event) {
val date = event.date
events[date] = events[date].orEmpty().minus(event)
updateAdapterForDate(date)
}
private fun updateAdapterForDate(date: LocalDate) {
eventsAdapter.events.clear()
eventsAdapter.events.addAll(events[date].orEmpty())
eventsAdapter.notifyDataSetChanged()
exThreeSelectedDateText.text = selectionFormatter.format(date)
}
fun uploadFirebase(){
val newEvent = mDatabaseReference.push()
newEvent.setValue(events)
}
override fun onStart() {
super.onStart()
}
override fun onStop() {
super.onStop()
}
}
There is no way you can add a property of type LocalDate in a Firebase Realtime database because it is not a supported data-type. However, there are two ways in which you can solve this:
You save the date as a ServerValue.TIMESTAMP, which basically means that you save the number of seconds that have elapsed since the Unix epoch. In this case, the server writes the current date in the database. To achieve this, please see my answer from the following post:
How to save the current date/time when I add new value to Firebase Realtime Database
You specify a custom long value for your date field. In this case, it's up to you to determine what date is written.
Unfortunately, there is no way you can combine these two options, you can use one or the other.
When talking about a LocalDate, we usually talk about an offset, in which case, this what I'll do. I'll store a Timestamp property, as explained at point one, that will let the server populate with the server Timestamp, as well as an offset property, that should be populated with the offset in days/hours.
I have cursor returned by an SQLite query, I would like to know correct approach for creating an Observable the emits each row in the cursor.
I created cursor observable as follows, please check if this is the correct:
Observable<Cursor> cursorObservable = Observable.create(new ObservableOnSubscribe<Cursor>() {
#Override
public void subscribe(ObservableEmitter<Cursor> e) throws Exception {
SQLDbHelper dbHelper = SQLDbHelper.getInstance(ctx);
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from " + MoviesContract.MovieEntry.TABLE_NAME, null);
if (cursor != null) {
try {
while (cursor.moveToNext() && !e.isDisposed()) {
e.onNext(cursor);
}
} catch (Exception exception) {
e.onError(exception);
} finally {
cursor.close();
}
}
if (!e.isDisposed()) {
e.onComplete();
}
}
});
I thank that you will have better results wrapping the rows into a Map and passing it through the stream than passing cursor itself.
class SimpleTest {
#Test
fun testCursorStream() {
val cursor = fakeCursor()
val stream = getCursorStream(cursor)
stream.subscribe {
Log.d("Test", it.entries.toString())
}
}
private fun fakeCursor() : Cursor {
val columns = arrayOf("id", "name", "age")
val cursor = MatrixCursor(columns)
val row1 = arrayOf(1, "Rodrigo", 26L)
val row2 = arrayOf(2, "Lucas", 23L)
val row3 = arrayOf(3, "Alan", 26L)
cursor.addRow(row1)
cursor.addRow(row2)
cursor.addRow(row3)
return cursor
}
private fun getCursorStream(cursor: Cursor) : Observable<Map<String, Any?>> {
return Observable.create<Map<String, Any?>> {
try {
if (!cursor.moveToFirst()) {
it.onCompleted()
return#create
}
val row = HashMap<String, Any?>()
do {
val lastColumnIndex = cursor.columnCount - 1
for (index in 0..lastColumnIndex) {
val name = cursor.getColumnName(index)
val type = cursor.getType(index)
when (type) {
Cursor.FIELD_TYPE_STRING -> row.put(name, cursor.getString(index))
Cursor.FIELD_TYPE_BLOB -> row.put(name, cursor.getBlob(index))
Cursor.FIELD_TYPE_FLOAT -> row.put(name, cursor.getFloat(index))
Cursor.FIELD_TYPE_INTEGER -> row.put(name, cursor.getInt(index))
Cursor.FIELD_TYPE_NULL -> row.put(name, null)
}
}
it.onNext(row)
} while (cursor.moveToNext())
it.onCompleted()
} catch (e: Exception) {
it.onError(e)
}
}
}
}
Hope that it helps.
I have creating this treetable
Now I want to sum up th children values and show the result in the parent cell under the related column. For example for Function 7 in column 2 and row 2 I want to right 2.0, and for Function 11 column 4 row 4 right 1.0 (function 12 + function 13)
Here is the code which produces the treetable.
root.setExpanded(true);
Set<String> combinedKeys = new HashSet<>(dc.getCombiFunc().keySet());
Set<String> funcAllKeys = new HashSet<>(dc.getSortedfuncAll().keySet());
funcAllKeys.removeAll(dc.getCombiFunc().keySet());
for (List<String> value : dc.getCombiFunc().values()) {
funcAllKeys.removeAll(value);
}
for (String valueremained : funcAllKeys) {
ArrayList<String> tempNameId = new ArrayList<>();
tempNameId.add(dc.getSortedfuncAll().get(valueremained));
// all elements which are not in combined functions (They are all
// orphan)
root.getChildren().add(new TreeItem<String>(tempNameId.get(0)));
}
// Getting Keys that have children//////
Set<String> keyFromcombined = new HashSet<>();
List<String> valueOfCombined = new ArrayList<String>();
for (Entry<String, List<String>> ent : dc.getCombiFunc().entrySet()) {
for (int i = 0; i < ent.getValue().size(); i++)
valueOfCombined.add(ent.getValue().get(i));
}
List<String> rootKeyList = new ArrayList<>();
for (String key : combinedKeys) {
if (!valueOfCombined.contains((key))) {
keyFromcombined.add(dc.getFuncAll().get(key));
rootKeyList.add(key);
}
}
String[] rootKeys = rootKeyList.toArray(new String[rootKeyList.size()]);
// ////////////////treetable////////////////////////////
treeTable.setRoot(root);
Arrays.stream(rootKeys).forEach(
rootKey -> root.getChildren().add(
createTreeItem(dc.getCombiFunc(), rootKey)));
// ////////////////First column/////////////////////////
TreeTableColumn<String, String> firstColumn = new TreeTableColumn<>("");
treeTable.getColumns().add(firstColumn);// Tree column
firstColumn.setPrefWidth(50);
firstColumn
.setCellValueFactory(new Callback<CellDataFeatures<String, String>, ObservableValue<String>>() {
public ObservableValue<String> call(
CellDataFeatures<String, String> p) {
return new ReadOnlyStringWrapper(p.getValue()
.getValue());
}
});
// //////////////////Rest Columns////////////////////////
for (Entry<String, String> ent : dc.getSortedAssignedOrg().entrySet()) {
TreeTableColumn<String, ArrayList<String>> col = new TreeTableColumn<>();
Label label = new Label(ent.getValue());
col.setGraphic(label);
label.setTooltip(new Tooltip(label.getText()));// tooltip for column
// headers
col.setPrefWidth(45);
// cell Value Factory////////////////////////
col.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<String, ArrayList<String>>, ObservableValue<ArrayList<String>>>() {
#Override
public ObservableValue<ArrayList<String>> call(
CellDataFeatures<String, ArrayList<String>> param) {
TreeMap<String, List<String>> temp = (TreeMap<String, List<String>>) dc
.getFuncTypeOrg().clone();
ArrayList<String> result = new ArrayList<>();
for (int i = 0; i < dc.getFuncTypeOrg().size(); i++) {
List<String> list = temp.firstEntry().getValue();
String key = temp.firstEntry().getKey();
if (list.get(1).equals(param.getValue().getValue())
&& !list.get(5).equals(label.getText())) {
result.add("white");
}
if (!root.isLeaf()) {
result.add("parent");
}
if (list.get(1).equals(param.getValue().getValue())
&& list.get(5).equals(label.getText())) {
result.add(0, list.get(2));// weight
if (list.size() > 6) {
result.add(1, list.get(list.size() - 1));// color
result.add(2, list.get(6));// App component
}
else
// result.add("white");
result.add("noOrg");
} else
temp.remove(key);
}
return new ReadOnlyObjectWrapper<ArrayList<String>>(result);
}
}); // end cell Value Factory
// //////////////cellfactory/////////////////////////
col.setCellFactory(new Callback<TreeTableColumn<String, ArrayList<String>>, TreeTableCell<String, ArrayList<String>>>() {
#Override
public TreeTableCell<String, ArrayList<String>> call(
TreeTableColumn<String, ArrayList<String>> param) {
return new TreeTableCell<String, ArrayList<String>>() {
public void updateItem(ArrayList<String> item,
boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setStyle("");
setText("");
} else if (item.contains("Green")) {
float weightInt = Float.parseFloat(item.get(0));
float res = weightInt * 1;
String resString = Float.toString(res);
this.setStyle("-fx-background-color:green");
setTooltip(new Tooltip(item.get(2)));
setText(resString);
} else if (item.contains("yellow")) {
this.setStyle("-fx-background-color:yellow");
setTooltip(new Tooltip(item.get(2)));
setText("0");
} else if (item.contains("white")) {
this.setStyle("-fx-background-color:linear-gradient(black, white); ");
// setText("DD");
} else if (item.contains("parent")) {
for (int i = 0; i < dc.getFuncTypeOrg().size(); i++) {
}
String text = param.getCellData(root).get(0);
// setText(text);
}
}
};
};
});// end cell factory
treeTable.getColumns().add(col);
}//end for loop col
TreeMap temp clones dc.getFuncTypeOrg(). In this TreeMap I have value for each child (color and the number). then in cellfactory i multiply value in color ( green = 1 and yellow = 0). Outside the loop I thought to make a treemap containg each parent as key and all it's children as value. Then I can sum up children values together and make a treemap in which first key is parent and as value the required value(or just string ArrayList ). After that I can check the name of cell in cellFactory and if it is a parent just right the value in the cell. I have been told how i can get treeitem values, and i am now here :
//after col loop ends
TreeMap<String, List<TreeItem<String>>> mytreemap = new TreeMap<>();
TreeMap<String, List<String>> parChild = new TreeMap<>();
for(TreeItem node: root.getChildren()){
if(!node.isLeaf())
mytreemap.put(node.getValue().toString(), node.getChildren());
}
for(Entry<String, List<TreeItem<String>>> ent: mytreemap.entrySet()){
for(TreeItem myItem : ent.getValue()){
// how can i fill parChild with parent as key and all its children as value?
System.out.println(ent.getKey()+" "+myItem.getValue());
}
}
treeTable.setPrefWidth(1200);
treeTable.setPrefHeight(500);
treeTable.setShowRoot(false);
treeTable.setTableMenuButtonVisible(true);
return treeTable; }
Here at setCellFactory
else if (item.contains("parent")) {
for (int i = 0; i < dc.getFuncTypeOrg().size(); i++) {
}
i can get the roots. Is there a way to do a recursion (up to the number of children and subchildren for that root cell) and add their value together and setText the parent cell to that value?
You can use onEditCommit method to add all childern values and show them in parent cell. For example
column1.setOnEditCommit((evt) -> {
//finalsing value of the cell
evt.getRowValue().getValue().setCellValue((evt.getNewValue()));
//Returns all the sibblings of the current cell
ObservableList<TreeItem> children = evt.getRowValue().getParent().getChildren();
int parentValue = 0;
for (TreeItem<> child : children) {
parentValue = parentValue + Integer.valueOf(child.getValue().getCellValue());
}
evt.getRowValue().getParent().getValue().setCellValue(parentValue);
});
On a DataGrid, setting alternatingItemColors will apply the color scheme to all of the columns of that grid. I'm looking for a way to define different alternating colors for each column. Is there a baked in way to do this?
Have a look on this:http://blog.flexexamples.com/2008/09/24/setting-background-colors-on-a-datagrid-column-in-flex/
I hope this would be helpful for you ;)
public class BlocksTable extends DataGrid
{
public static const VALID_COLOR:uint = 0xDBAB21;
public static const INVALID_COLOR:uint = 0xC7403E;
public function BlocksTable()
{
super();
}
override protected function drawRowBackground(s:Sprite, rowIndex:int, y:Number, height:Number, color:uint, dataIndex:int):void
{
var contentHolder:ListBaseContentHolder = ListBaseContentHolder(s.parent);
var background:Shape;
if (rowIndex < s.numChildren)
{
background = Shape(s.getChildAt(rowIndex));
}
else
{
background = new FlexShape();
background.name = "background";
s.addChild(background);
}
background.y = y;
// Height is usually as tall is the items in the row, but not if
// it would extend below the bottom of listContent
var height:Number = Math.min(height,
contentHolder.height -
y);
var g:Graphics = background.graphics;
g.clear();
var fillColor:uint;
if(dataIndex < this.dataProvider.length)
{
if(this.dataProvider.getItemAt(dataIndex).IS_VALID)
{
fillColor = VALID_COLOR;
}
else
{
fillColor = INVALID_COLOR;
}
}
else
{
fillColor = color;
}
g.beginFill(fillColor, getStyle("backgroundAlpha"));
g.drawRect(0, 0, contentHolder.width, height);
g.endFill();
}
}