I'm not sure if this is the right Stack Exchange site to ask good name for bars in Gantt Chart.
Data Structure
public class GanttChartData
{
public ICollection<GanttBarData> BarCollection { get; set; }
}
public class GanttBarData
{
public string Name { get; set; }
public double Length { get; set; }
}
Question Should I use Length or Width to represent length of a bar? I know it would be horizontal bar always.
As Wikipedia states:
In geometric measurements, length is the longest dimension of an
object.
Hence your choice of BarLength is correct as the horizontal length is (almost!) always going to be the longest dimension of a bar in your chart.
Related
I want to add a Hyperlink (or a text that is styled like a Hyperlink) in a TableViewerColumn Cell.
I tried this and this.
Summarize: I either get a clickable Hyperlink for which the text is cropped (the column width is too small) or I get a link that is not clickable (MouseListener missing, no cursor).
Both tries are making use of a StyledCellLabelProvider for the TableViewerColumn. The first try does this:
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column .getColumn().setText(TITLE);
column .setLabelProvider(new MyHyperlinkLabelProvider());
However, the text in the cell is cropped and I have no idea how to set the column width so that the text fits in the cell. I tried with using pack(), but it had no effect.
private final class MyHyperlinkLabelProvider extends StyledCellLabelProvider {
private MyHyperlinkLabelProvider() {
}
#Override
public void update(ViewerCell cell) {
TableItem item = (TableItem)cell.getItem();
String myText= "Hyperlink text, unfortunately cropped";
link = new MyHyperlink((Composite)cell.getViewerRow().getControl(), SWT.NONE);
toolkit.adapt(link);
link.setText(myText);
TableEditor editor = new TableEditor(item.getParent());
editor.grabHorizontal = true;
editor.grabVertical = true;
editor.setEditor(link, item, cell.getColumnIndex());
GridDataFactory.fillDefaults().applyTo(editor.getEditor());
editor.layout();
link.addMouseListener(new MouseAdapter() {
#Override
public void mouseUp(MouseEvent event) {
super.mouseUp(event);
if (event.getSource() instanceof MyHyperlink) {
MyHyperlink link = (MyHyperlink)event.getSource();
System.out.println("Label was clicked: " + link.getText());
}
}
});
super.update(cell);
}
}
private class MyHyperlink extends Hyperlink {
public MyHyperlink(Composite parent, int style) {
super(parent, style);
this.setUnderlined(true);
}
}
The less preferred alternative is given in the second link. If I cannot get the column width correct, I'd go with this.
The second link suggests to try it with StyledString instead of Hyperlink. The StyledString at least is shown in full width and the column has the correct width. However, you cannot add a MouseListener to a StyledString. Only on the table, but that doesn't help.
private final class MyHyperlinkLabelProvider extends StyledCellLabelProvider {
private MyHyperlinkLabelProvider() {
}
#Override
public void update(ViewerCell cell) {
TableItem item = (TableItem)cell.getItem();
String mytext= "This is the hyperlink text";
/* make text look like a link */
StyledString text = new StyledString();
StyleRange myStyledRange =
new StyleRange(0, phase.length(), Display.getCurrent().getSystemColor(SWT.COLOR_BLUE), null);
myStyledRange.underline = true;
text.append(mytext, StyledString.DECORATIONS_STYLER);
cell.setText(text.toString());
StyleRange[] range = {myStyledRange };
cell.setStyleRanges(range);
super.update(cell);
}
}
To have the column size computed correctly, the cell text has to be set. Although the Hyperlink is what should be displayed link.setText(myText); is not enough. cell.setText(myText) is needed, too.
One can see it in the second snippet, for which the column size is correct. It is because of the cell.setText() call.
I am working on a xamarin.forms application where I need to measure the height of the navigation bar. How do I measure it? I tried to follow this but I don't understand where to insert this code:
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
}
return 0;
You are on the right track. The problem is that your app is cross platform and the navigation bar is a Android-only feature. Because you probably need to access the navigation bar height from within the shared code, you will need to use Dependency injection. This is thoroughly described here.
In short you will have to write a namespace like this:
public interface INavigationBarInfo
{
int Height { get; };
}
And implement it for Android within the Android project:
public class NavigationBarInfo : INavigationBarInfo
{
public int Height => RetrieveHeight();
private void RetrieveHeight()
{
//android specific code to retrieve the navigation bar height
//you can use the answer you linked to in your question
}
}
I'm using code generation to generate interfaces that correspond to table definition in a certain database.
Since the database is very messy I get around 500 interfaces (for 500 tables) each with it's own definition.
Some of the interfaces can inherit from each other, and for some a common interface can be extracted to minimize code definition.
For example:
interface One
{
int FirstField { get; set; }
bool SecondField { get; set; }
DateTime ThirdField { get; set; }
}
interface Two
{
int FirstField { get; set; }
DateTime ThirdField { get; set; }
double FourthField { get; set; }
}
I would like to perform some kind of minimization on the code to have minimum amount of it generated (through multiple inheritance and common code extraction).
From above example I would need to get something like:
interface OneTwoCommon
{
int FirstField { get; set; }
DateTime ThirdField { get; set; }
}
interface One : OneTwoCommon
{
bool SecondField { get; set; }
}
interface Two : OneTwoCommon
{
double FourthField { get; set; }
}
Which branch of algorithms deals with these problems?
Where do I start looking up those algorithms?
I don't even know what to write in Google to get relevant results.
I figured out a simple algorithm.
define Surface of interface as number of other interfaces that implement it, times the number of properties of that interface
the goal is to construct a new interface, with subset of all used properties, with maximum possible surface
Initialization:
first we order descedning all properites by number of interfaces that contain it, into LProperties (so most used properties will be on top)
select first property (P1) from LProperties, create new interface ITemp with only that property
pop P1 from LProperties
calculate Surface of ITemp (number of existing interfaces that can implement it times number of properties)
Iteration:
select first property from LProperties (now P2), put it in ITemp (note: P2 is not P1 since we popped P1)
new Surface
new Surface > old Surface, remove P2 from LProperties, save it to ITemp, remember Surface
*, remove P2 from ITemp
Iteration:
next property from LProperties (now P3), put it in ITemp (note: P2 is still in LProperties, but we already processed it)
if new Surface > old Surface remove P3 from LProperties, save it to ITemp, else remove P3 from ITemp
Hello guys I am building a chat server where I use a textfield on the screen to type in the chat message that the user writes, the idea is that it works like a bubble over a persons head when he types a message.
my question is in order to not make a textbox that is too large or too small is there a way to make the textbox resize (trim if you will) so it adjust to the text written in the textfield?
P.S. I'm using JavaFx scenebuilder to do all of this.
You can use computeTextWidth method in the com.sun.javafx.scene.control.skin.Utils. the method is used in javafx.scene.control.Label class to calculate the minimum width for label content.
I solved my problem as below:
field.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> ob, String o,
String n) {
// expand the textfield
field.setPrefWidth(TextUtils.computeTextWidth(field.getFont(),
field.getText(), 0.0D) + 10);
}
});
I have added a listener to textProperty, and with every text change i change the prefWidth of textfield.
Note: as long as the Utils.computeTextWidth() is not public, I have copied the source code to a new class (TextUtils).
Here is the full source code:
package me.jone30rw.fxcontrol;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextBoundsType;
public class TextUtils {
static final Text helper;
static final double DEFAULT_WRAPPING_WIDTH;
static final double DEFAULT_LINE_SPACING;
static final String DEFAULT_TEXT;
static final TextBoundsType DEFAULT_BOUNDS_TYPE;
static {
helper = new Text();
DEFAULT_WRAPPING_WIDTH = helper.getWrappingWidth();
DEFAULT_LINE_SPACING = helper.getLineSpacing();
DEFAULT_TEXT = helper.getText();
DEFAULT_BOUNDS_TYPE = helper.getBoundsType();
}
public static double computeTextWidth(Font font, String text, double help0) {
// Toolkit.getToolkit().getFontLoader().computeStringWidth(field.getText(),
// field.getFont());
helper.setText(text);
helper.setFont(font);
helper.setWrappingWidth(0.0D);
helper.setLineSpacing(0.0D);
double d = Math.min(helper.prefWidth(-1.0D), help0);
helper.setWrappingWidth((int) Math.ceil(d));
d = Math.ceil(helper.getLayoutBounds().getWidth());
helper.setWrappingWidth(DEFAULT_WRAPPING_WIDTH);
helper.setLineSpacing(DEFAULT_LINE_SPACING);
helper.setText(DEFAULT_TEXT);
return d;
}
}
In JavaFX 8, there is a solution for that, here is the code:
TextField tf = new TextField();
// Set Max and Min Width to PREF_SIZE so that the TextField is always PREF
tf.setMinWidth(Region.USE_PREF_SIZE);
tf.setMaxWidth(Region.USE_PREF_SIZE);
tf.textProperty().addListener((ov, prevText, currText) -> {
// Do this in a Platform.runLater because of Textfield has no padding at first time and so on
Platform.runLater(() -> {
Text text = new Text(currText);
text.setFont(tf.getFont()); // Set the same font, so the size is the same
double width = text.getLayoutBounds().getWidth() // This big is the Text in the TextField
+ tf.getPadding().getLeft() + tf.getPadding().getRight() // Add the padding of the TextField
+ 2d; // Add some spacing
tf.setPrefWidth(width); // Set the width
tf.positionCaret(tf.getCaretPosition()); // If you remove this line, it flashes a little bit
});
});
tf.setText("Hello World!");
In JavaFX 2.2 this code works with little limitations. You can't set the Font(so if you do not use the std-font, you must set it manually).
You can't get the padding from a TextField(so if you know the padding, write it hardcoded).
Happy Coding,
Kalasch
Since JavaFX 8, this is by far the simplest:
textField.prefColumnCountProperty().bind(textField.textProperty().length());
It is time to do some coding behind the scenes(builder) :).
The following code chunk is not a neat solution but better than none. :)
// define width limits
textField.setMinWidth(50);
textField.setPrefWidth(50);
textField.setMaxWidth(400);
// add listner
textField.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
textField.setPrefWidth(textField.getText().length() * 7); // why 7? Totally trial number.
}
});
No font dependent magic required if you use setPrefColumnCount
tf.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> ob, String o, String n) {
tf.setPrefColumnCount(tf.getText().length() +1);
}
});
The best / easiest way to do this is to use JavaFX's "USE_COMPUTED_SIZE" option. You can either define it in the FXML, or programatically like this:
TextField textField = new TextField("hello");
textField.setPrefWidth(Control.USE_COMPUTED_SIZE);
Trying to create a custom cyclical horizontal manager which will work as follows. It will control several field buttons where the buttons will always be positioned so that the focused button will be in the middle of the screen. As it is a cyclical manager once the focus moves to the right or left button, it will move to the center of the screen and all the buttons will move accordingly (and the last button will become the first to give it an cyclic and endless list feeling)
Any idea how to address this?
I tried doing this by implementing a custom manager which aligns the buttons according to the required layout. Each time moveFocus() is called I remove all fields (deleteAll() ) and add them again in the right order.
Unfortunately this does not work.
Using HorizontalButtonFieldSet class from KB How to - Implement advanced buttons, fields, and managers:
class CentricHManager extends HorizontalButtonFieldSet {
int focusedFieldIndex = 0;
public void focusChangeNotify(int arg0) {
super.focusChangeNotify(arg0);
int focusedFieldIndexNew = getFieldWithFocusIndex();
if (focusedFieldIndexNew != focusedFieldIndex) {
if (focusedFieldIndexNew - focusedFieldIndex > 0)
switchField(0, getFieldCount() - 1);
else
switchField(getFieldCount() - 1, 0);
}
}
private void switchField(int prevIndex, int newIndex) {
Field field = getField(prevIndex);
delete(field);
insert(field, newIndex);
}
public void add(Field field) {
super.add(field);
focusedFieldIndex = getFieldCount() / 2;
setFieldWithFocus(getField(focusedFieldIndex));
}
}