I wondered if anyone knew whether it was possible to remove the '+' Sign that appears next to the root item in a GWT Tree? I didn't see a CSS rule to handle it. Can one replace the + sign with say, a GIF?
(Adapted code from GWT manual below, for illustrative purposes)
TreeItem root = new TreeItem("root"); // Wish to remove + sign from next to this item
root.addItem("item0");
root.addItem("item1");
root.addItem("item2");
root.setState(true, true);
// Add a CheckBox to the tree
TreeItem item = new TreeItem(new CheckBox("item3"));
root.addItem(item);
Tree t = new Tree();
t.addItem(root);
// Add it to the root panel.
RootPanel.get().add(t);
CSS styling does not apply to this at all. Rather, it requires using a different constructor for tree.. If you set spacer.png to a 1x1 transparent PNG it will remove the + signs. Here is the full code I used.
The correct way to do it is as follows:
public interface MyResources extends ClientBundle {
public static final MyResources INSTANCE = GWT.create(MyResources.class);
#Source("spacer.png")
public ImageResource leaf();
}
public class TreeImagesExample implements Tree.Resources
{
#Override
public ImageResource treeClosed() {
// TODO Auto-generated method stub
return MyResources.INSTANCE.leaf();
}
#Override
public ImageResource treeLeaf() {
// TODO Auto-generated method stub
return MyResources.INSTANCE.leaf();
}
#Override
public ImageResource treeOpen() {
// TODO Auto-generated method stub
return MyResources.INSTANCE.leaf();
}
}
Main Function:
TreeImagesExample tx= new TreeImagesExample();
Tree t = new Tree(tx);
t.addItem(root);
For this to work properly, we will also need a SelectionHandler, of course, so that we can register tree clicks on the tree items rather than the (now non-existent) + signs.
You'll have to use CSS to override the plus icon image, which is set as the background image of the item with a left-margin to move the text off of it.
The root item doesn't have its own specific style so you'll have to add a style name (i.e., CSS class) on the tree item yourself and remove the background image yourself, in CSS.
Related
How can I prevent column width resizing? I have a table, and I'm wondering if I can simply disable the option to drag to resize width of the columns. Is there any way to do this, or will I have to manually set the max and min width of each column just so that it can't be manipulated by the user? The problem with this is that the text in the title/header of my table is smaller than what's in the row underneath it. Setting the width to the column width forces it smaller, and then you can't see the info in the cell underneath.
Also, if there's a way to disable rearranging the columns, that'd be nice too. I basically want what I have set to not be changed at all. If this can't be done, I might just replace each table with an image of itself, so that it can't be manipulated at all.
Prevent Resizing Columns
From here, we can know that setResizable(boolean) allows you to choose whether the user can resize a column. Setting the max and min width to the same value does prevents the user from resizing the column, but not a preferred method. Also, the user will see the resizing cursor but not the default cursor when attempting to resize the column.
Prevent Reordering Columns
JavaFX 9
For preventing the user from reordering the columns, there isn't a straight-forward solution until JavaFX 9, which introduces setReorderable(boolean), isReorderable(), reorderableProperty methods, and the reorderable field in the TableColumnBase class. Here is a snippet of the source code:
package javafx.scene.control;
//some imports and JavaDoc comments
#IDProperty("id")
public abstract class TableColumnBase<S,T> implements EventTarget, Styleable {
//some code
// --- Reorderable
/**
* A boolean property to toggle on and off the 'reorderability' of this column
* (with drag and drop - reordering by modifying the appropriate <code>columns</code>
* list is always allowed). When this property is true, this column can be reordered by
* users simply by dragging and dropping the columns into their desired positions.
* When this property is false, this ability to drag and drop columns is not available.
*
* #since 9
*/
private BooleanProperty reorderable;
public final BooleanProperty reorderableProperty() {
if (reorderable == null) {
reorderable = new SimpleBooleanProperty(this, "reorderable", true);
}
return reorderable;
}
public final void setReorderable(boolean value) {
reorderableProperty().set(value);
}
public final boolean isReorderable() {
return reorderable == null ? true : reorderable.get();
}
//some code
}
If your application bases on JavaFX 9, then you are lucky. Simply invoke setReorderable(false) on your desired table column and there you go.
JavaFX 8
If your application bases on JavaFX 8 or older versions, you can use com.sun.javafx.scene.control.skin.TableHeaderRow, which has isReordering, setReordering, reorderingProperty methods, and reorderingProperty field. Here is a snippet of the source code:
package com.sun.javafx.scene.control.skin;
//some imports and JavaDoc comments
public class TableHeaderRow extends StackPane {
//some code
private BooleanProperty reorderingProperty = new BooleanPropertyBase() {
#Override protected void invalidated() {
TableColumnHeader r = getReorderingRegion();
if (r != null) {
double dragHeaderHeight = r.getNestedColumnHeader() != null ?
r.getNestedColumnHeader().getHeight() :
getReorderingRegion().getHeight();
dragHeader.resize(dragHeader.getWidth(), dragHeaderHeight);
dragHeader.setTranslateY(getHeight() - dragHeaderHeight);
}
dragHeader.setVisible(isReordering());
}
#Override
public Object getBean() {
return TableHeaderRow.this;
}
#Override
public String getName() {
return "reordering";
}
};
public final void setReordering(boolean value) { reorderingProperty().set(value); }
public final boolean isReordering() { return reorderingProperty.get(); }
public final BooleanProperty reorderingProperty() { return reorderingProperty; }
//some code
}
The methods and fields work the same as the one in TableColumnBase in JavaFX 9, just with different names.
You want to obtain the TableHeaderRow object as a children of the skin of the TableView:
TableView<MyType> table = new TableView<MyType>();
//some code
//DISPLAY THE TABLE OR GETSKIN WILL RETURN NULL
com.sun.javafx.scene.control.skin.TableHeaderRow header = null;
for (Node node : table.getSkin().getChildren())
if (node instanceof com.sun.javafx.scene.control.skin.TableHeaderRow)
header = (com.sun.javafx.scene.control.skin.TableHeaderRow) node;
if (header == null); //Table not rendered
header.setReorderable(false);
You must have the TableView rendered before accessing the skin, because the TableViewSkin obtained from TableView.getSkin() is a visual representation of user interface controls. As the official JavaFx JavaDoc says, Skin is a
Base class for defining the visual representation of user interface
controls by defining a scene graph of nodes to represent the skin. A
user interface control is abstracted behind the Skinnable interface.
Therefore, the Skin will be null if the TableView is not rendered because there is nothing visual to represent.
Note that the second method cannot be used in Java 9 or later due to the modules in Java API block your access towards any sun packages.
EDIT:
In JavaFX 8 or older, there is a method called impl_setReorderable(boolean) which is deprecated, but works flawlessly, pretty much same as setReorderable(boolean) in JavaFX 9.
I have a problem with override Custom Animation on my Fragment. I have on my Home view three buttons (First, Second and Third) and when I'm inside this views I want swipe between those view and I need swipe animation effect from left to right and from right to left etc..
For Example my SecondFragments looks like this:
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
public class SecondFragment : BaseFragment<SecondViewModel>, View.IOnTouchListener
{
private Easter _easter;
protected override int FragmentId => Resource.Layout.fragment_second;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = base.OnCreateView(inflater, container, savedInstanceState);
_easter = new Easter(new KonamiCode());
var easyEgg = new CustomEgg("Easy")
.WatchForSequence(Command.SwipeLeft(), Command.SwipeRight());
_easter = new Easter(easyEgg);=
_easter.CommandDetected += cmd => DoSwipe(cmd.Value);
var coreLayout = view.FindViewById<LinearLayout>(Resource.Id.coreLayout);
coreLayout?.SetOnTouchListener(this);
return view;
}
private void DoSwipe(string swipeText)
{
if (swipeText.Equals("LEFT"))
{
Activity.OverridePendingTransition(Resource.Animator.slide_to_right, Resource.Animator.slide_from_left);
}
if (swipeText.Equals("RIGHT"))
{
Activity.OverridePendingTransition(Resource.Animator.slide_to_left, Resource.Animator.slide_from_right);
}
ViewModel.SwipeView(swipeText);
}
public bool OnTouch(View v, MotionEvent e)
{
_easter.OnTouchEvent(e);
return true;
}
}
Method ViewModel.SwipeView looks like:
public override void SwipeView(string swipeText)
{
if (swipeText.Equals("RIGHT"))
{
Close(this);
UserDialogs.Instance.Toast("RIGHT SWIPE!");
ShowViewModel<FirstViewModel>();
}
if (swipeText.Equals("LEFT"))
{
Close(this);
UserDialogs.Instance.Toast("LEFT SWIPE!");
ShowViewModel<ThirdViewModel>();
}
}
I tried Activity.OverridePendingTransition for this but it doesnt work. I tried something with TransactionManager but still doesnt work. I need just override animations only for these three view no for whole app.
For example my test project is HERE on github.
I tried Activity.OverridePendingTransition for this but it doesnt work.
OverridePendingTransition allows you to specify a custom animation when starting an activity from outside the Context of the current top Activity. That means OverridePendingTransition method only be called immediately after one of the flavors of startActivity(Intent) or finish() to specify an explicit transition animation to perform next. So when you swipe between those Fragment, it has no effect.
Difference between Animator folder and Anim fodler.
An animation resource can define one of two types of animations: Property Animation and View Animation.
Property Animation
File Location:
Resource/animator/filename.xml
SYNTAX:
The file must have a single root element: either <set>, <objectAnimator>, or <valueAnimator>. You can group animation elements together inside the <set> element, including other <set> elements.
View Animation
File Location:
Resource/anim/filename.xml
SYNTAX:
The file must have a single root element: either an <alpha>, <scale>, <translate>, <rotate>, or <set> element that holds a group (or groups) of other animation elements (even nested <set> elements).
Since your animation use translate, I suggest you put these xml file in Resource/anim folder.
I need just override animations only for these three view no for whole app.
Since your base Activity is MvxCachingFragmentCompatActivityas, you can override OnBeforeFragmentChanging method to set a custom transition animation.
public override void OnBeforeFragmentChanging(MvvmCross.Droid.Shared.Caching.IMvxCachedFragmentInfo fragmentInfo, Android.Support.V4.App.FragmentTransaction transaction)
{
//Replace this animation with your own animation.
transaction.SetCustomAnimations(
// Your entrance animation xml reference
Resource.Animation.abc_fade_in,
// Your exit animation xml reference
Resource.Animation.abc_fade_out,
Resource.Animation.abc_fade_in,
Resource.Animation.abc_fade_out);
base.OnBeforeFragmentChanging(fragmentInfo, transaction);
}
SetCustomAnimations set specific animation resources to run for the fragments that are entering and exiting in this transaction. The popEnter and popExit animations will be played for enter/exit operations specifically when popping the back stack.
FragmentTransaction setCustomAnimations (int enter,
int exit,
int popEnter,
int popExit)
EDIT :
Custom animation for every swipe between Fragment, for every Fragment, you could custom animation like this :
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
public class SecondFragment : BaseFragment<SecondViewModel>, View.IOnTouchListener
{
private void DoSwipe(string swipeText)
{
if (swipeText.Equals("LEFT"))
{
FragmentManager.BeginTransaction()
.SetCustomAnimations(Resource.Animation.slide_from_left, Resource.Animation.slide_from_right)
.Replace(Resource.Id.content_frame,ThirdFragment.NewInstance(null))
.Commit();
}
if (swipeText.Equals("RIGHT"))
{
...
}
ViewModel.SwipeView(swipeText);
}
}
They best way you could achieve this is by using a ViewPager that contains your fragments. I implemented the exact thing yesterday, you can look at this example on how to use this with MvvmCross.
On Button Click, I generate 4 pages on my PDF, i added this image to provide a background image
string imageFilePath = parent + "/Images/bg_image.jpg";
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(imageFilePath);
jpg.ScaleToFit(1700, 1000);
jpg.Alignment = iTextSharp.text.Image.UNDERLYING;
jpg.SetAbsolutePosition(0, 0);
document.Add(jpg);
It works only with 1 page, but when i generate a PDF that contains many records and have several pages, the bg image is only at the last page. I want to apply the background image to all of the pages.
It is normal that the background is added only once, because you're adding it only once.
If you want to add content to every page, you should not do that manually because you don't know when a new page will be created by iText. Instead you should use a page event. This is explained in Chapter 5 of my book (for the C# version of the examples, see http://tinyurl.com/itextsharpIIA2C05 ).
A nice example can be found in the Stationery example in chapter 6: Stationery.cs
The idea is to create an implementation of the PdfPageEvent interface, for instance by extending the PdfPageEventHelper class and overriding the OnEndPage() method:
class TemplateHelper : PdfPageEventHelper {
private Stationery instance;
public TemplateHelper() { }
public TemplateHelper(Stationery instance) {
this.instance = instance;
}
/**
* #see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(
* com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
*/
public override void OnEndPage(PdfWriter writer, Document document) {
writer.DirectContentUnder.AddTemplate(instance.page, 0, 0);
}
}
In this case, we add a PdfTemplate, but it is very easy to add an Image replacing the Stationery instance with an Image instance and replacing the AddTemplate() method with the AddImage() method.
Once you have an instance of your custom page event, you need to declare it to the PdfWriter instance:
writer.PageEvent = new TemplateHelper(this);
From that moment on, your OnEndPage() method will be executed each time a page is finalized.
Warning: as documented you shall not use the OnStartPage() method to add content in a page event!
Update:
The final result would look more or less like this:
class ImageBackgroundHelper : PdfPageEventHelper {
private Image img;
public ImageBackgroundHelper(Image img) {
this.img = img;
}
/**
* #see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(
* com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
*/
public override void OnEndPage(PdfWriter writer, Document document) {
writer.DirectContentUnder.AddImage(img);
}
}
Now you can use this event like this:
string imageFilePath = parent + "/Images/bg_image.jpg";
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(imageFilePath);
jpg.ScaleToFit(1700, 1000);
jpg.SetAbsolutePosition(0, 0);
writer.PageEvent = new ImageBackgroundHelper(jpg);
Note that 1700 and 1000 seems quite big. Are you sure those are the dimensions of your page?
I need to set up specific styles of Cell Browser cells in GWT from a CSS file. Any pointers on how to do it
If you are using 2.4 or 2.5 sdk of GWT
Override getCellStyleNames() while creating column.
TextColumn<String> col= new TextColumn<String>() {
#Override
public String getCellStyleNames(Context context, String object) {
return "yourStylee";
}
#Override
public String getValue(String object) {
return object.getName();
}
};
};
If its cell
public void render(com.google.gwt.cell.client.Cell.Context context, Meeting object, SafeHtmlBuilder sb) {
sb.append(SafeHtmlUtils.fromString(" <div class=youclass><table>"));
// Code goes here
sb.append(SafeHtmlUtils.fromString("<table> </div>"));
You should be able to set the css style on any widget using methods from UIObject. In this case something like this should work:
cellBrowserInstance.setStylePrimaryName("newStyle");
with "newStyle" being listed in your CSS.
How can i have Grid with cell which can act as container in GXT 3 so that they can hold any object from other container to any widget.
I'm working on small app which has row expander grid. GXT demo has good example of it.
From class hierarchy it was clear that Grid cells are Cell interface which allows for using render() method so I can add any html code that can displayed in it.
But i wanted to create a cell widget which can have add() method for allowing to add other widgets such as ContentPanel to any other widget
Any suggestion ?
This is the code i wrote. Not a perfect one, but does the work.
public class MyRowExpander extends
RowExpander<GridModel> {
public MyRowExpander (
IdentityValueProvider<GridModel> valueProvider,
AbstractCell<GridModel> contentCell) {
super(valueProvider, contentCell);
}
#Override
protected boolean beforeExpand(GridModel model, Element body,
XElement row, int rowIndex) {
super.beforeExpand(model, body, row, rowIndex);
BeforeExpandItemEvent<GridModel> e = new BeforeExpandItemEvent<GridModel>(
model);
if (!e.isCancelled()) {
if (body.hasChildNodes())
body.removeChild(body.getChild(0));
body.setInnerText("");
Widget customWidget = getWidget(model);
body.appendChild(customWidget.getElement());
ComponentHelper.doAttach(customWidget);
return true;
}
return false;
}