How to make outer pane scroll instead of inner one - richtextfx

Firstly, as you probably noticed in tags, I use RichTextFX. CodeArea is just its text area with some features.
I have ScrollPane with inner elements:
ScrollPane
| AnchorPane
| | VBox
| | | HBox
| | | | Label
| | | | CodeArea
| | | HBox
| | | | Label
| | | | CodeArea
| | | HBox
| | | | Label
| | | | CodeArea
...........................
When I'm trying to scroll while my cursor isn't hovering CodeArea, ScrollPane scrolling like it should do.
But if my cursor is on CodeArea, as I assume, it trying to scroll the CodeArea, even if there is nothing to scroll (content fits well).
ScrollEvent isn't being called on ScrollPane, AnchorPane nor CodeArea, but VBox.
I tried to bind properties like scrollPane.onScrollProperty().bind(vBox.onScrollProperty()) or scrollPane.onScrollProperty().bind(codeArea.onScrollProperty()) and many others but that didn't work.
This question doesn't affect classic TextArea.
How to make ScrollPane scroll instead of CodeArea when hovering CodeArea?
You can also use this example to reproduce the problem:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.scene.control.ScrollPane;
import org.fxmisc.richtext.CodeArea;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
ScrollPane scrollPane = new ScrollPane();
VBox vBox = new VBox();
scrollPane.setContent(vBox);
CodeArea codeArea = new CodeArea();
codeArea.setPrefHeight(2000);
Label label = new Label("Can you scroll here while hovering code area?");
vBox.getChildren().addAll(codeArea, label);
for (int i = 0; i < 256; i++) {
codeArea.appendText("Sample text\n");
}
Scene scene = new Scene(scrollPane, 400, 400);
stage.setScene(scene);
stage.show();
}
}

In your example do:
codeArea.addEventFilter( ScrollEvent.ANY, scroll ->
{
vBox.fireEvent( scroll );
scroll.consume();
});

Related

Clang AST Matcher: No CXXMethodDecl for `operator()`?

I have the following struct definition in a file:
template <class... EventArgs>
struct banana {
template <class... Args>
void operator()(Args&&... args) const {
_f(std::forward<Args>(args)...);
}
private:
std::function<void(EventArgs...)> _f;
};
Using -ast-dump -fsyntax-only, I can clearly see multiple CXXRecordDecls in the dump that refer to banana, as well as CXXMethodDecls that refer to operator():
`-ClassTemplateDecl 0x7fb23c11e028 <./test_files/templates.cpp:12:1, line:21:1> line:13:8 banana
|-TemplateTypeParmDecl 0x7fb23c11df08 <line:12:11, col:20> col:20 referenced class depth 0 index 0 ... EventArgs
|-CXXRecordDecl 0x7fb23c11df90 <line:13:1, line:21:1> line:13:8 struct banana definition
| |-CXXRecordDecl 0x7fb23c11e300 <line:13:1, col:8> col:8 implicit struct banana
| |-FunctionTemplateDecl 0x7fb23c11e668 <line:14:5, line:17:5> line:15:10 operator()
| | |-TemplateTypeParmDecl 0x7fb23c11e398 <line:14:15, col:24> col:24 referenced class depth 1 index 0 ... Args
| | `-CXXMethodDecl 0x7fb23c11e5d0 <line:15:5, line:17:5> line:15:10 operator() 'void (Args &&...) const'
| | etc., etc.
My MatchFinder::MatchCallback subclass is being run over the CXXRecordDecl for event, however methods() is coming back with an empty range:
void ClassInfo::run(const MatchFinder::MatchResult& Result) {
auto clas = Result.Nodes.getNodeAs<clang::CXXRecordDecl>("class");
for (const auto& method : clas->methods()) {
// Not getting run - methods() is empty?
}
}
What am I missing?
Well, clas->methods() only returns CXXMethodDecls in the top level of the struct.
But in your struct, there is only FunctionTemplateDecl.
So, you may wanna do something like this:
for (const auto &decl : clas->decls()) {
if (auto *templ = dyn_cast<FunctionTemplateDecl>(&decl)) {
// Use templ->getTemplatedDecl to get FunctionDecl.
}
}
Note. I haven't actually tested nor compiled that code, but hopefully, you get the idea from it.

Issue in using managers

I want to dispaly some data at the top of the screen and some at the end of the screen,creating two different managers,the issue is after running i cannot see any data on the screen
public NativeScreen() {
super();
LabelField title = new LabelField("Calendar DatePicker",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
hrzManager = new HorizontalFieldManager() {
protected void paintBackground(Graphics graphics) {
graphics.setBackgroundColor(0x0007F5ED);
graphics.clear();
super.paint(graphics);
}
};
hrzManager.add(title);
VerticalFieldManager verticalFieldManagerUpper = new VerticalFieldManager(Manager.NO_VERTICAL_SCROLL | Manager.NO_HORIZONTAL_SCROLL |
Manager.USE_ALL_HEIGHT | Manager.USE_ALL_WIDTH ) ;
verticalFieldManagerUpper.add(hrzManager);
//Add the manager to the screen.
this.add(verticalFieldManagerUpper);
VerticalFieldManager verticalFieldManager = new VerticalFieldManager(Manager.NO_VERTICAL_SCROLL | Manager.NO_HORIZONTAL_SCROLL |
Manager.USE_ALL_HEIGHT | Manager.USE_ALL_WIDTH ) ;
HorizontalFieldManager horizontalFieldManager = new HorizontalFieldManager(HorizontalFieldManager.USE_ALL_WIDTH | HorizontalFieldManager.USE_ALL_HEIGHT);
ImageButtonField bitmapField = new ImageButtonField(Bitmap.getBitmapResource("pimdemo_jde.png"), Field.FIELD_BOTTOM);
horizontalFieldManager.add(bitmapField);
ImageButtonField bitmapField1 = new ImageButtonField(Bitmap.getBitmapResource("attachmentdemo_jde.png"), Field.FIELD_BOTTOM);
horizontalFieldManager.add(bitmapField1);
//Add the fields to the manager.
verticalFieldManager.add(horizontalFieldManager);
//Add the manager to the screen.
this.add(verticalFieldManager);
Use the set status and set title -
setTitle(field);
setStatus(field);

Stuck on first attempt at Blackberry App

attempting a first Blackberry App.
It will display diary data (eventually).
I'm just trying to get things working bit by bit.
I can't get the buttons to work in the simulator ie I click them and nothing happens.
Any help appreciated.
Code is below (hopefully ok formatted - first post so apologies if not).
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
/**
* A class extending the MainScreen class.
*/
public class MyScreen extends MainScreen implements FieldChangeListener
{
/**
* Creates a new MyScreen object
*/
ButtonField lastWeek;
ButtonField todayWeek;
ButtonField nextWeek;
LabelField Monday;
LabelField MondayData;
LabelField Tuesday;
LabelField TuesdayData;
LabelField Wednesday;
LabelField WednesdayData;
LabelField Thursday;
LabelField ThursdayData;
LabelField Friday;
LabelField FridayData;
LabelField Satday;
LabelField SaturdayData;
LabelField Sunday;
LabelField SundayData;
public MyScreen(){
LabelField banner = new LabelField("Diary",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField title = new LabelField("Week starting...",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField Monday = new LabelField("Monday",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField MondayData = new LabelField("MondayData",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField Tuesday = new LabelField("Tuesday",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField TuesdayData = new LabelField("TuesdayData",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField Wednesday = new LabelField("Wednesday",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField WednesdayData = new LabelField("WednesdayData",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField Thursday = new LabelField("Thursday",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField ThursdayData = new LabelField("ThursdayData",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField Friday = new LabelField("Friday",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField FridayData = new LabelField("FridayData",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField Saturday = new LabelField("Saturday",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField SaturdayData = new LabelField("SaturdayData",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField Sunday = new LabelField("Sunday",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
LabelField SundayData = new LabelField("Sundaydata",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
HorizontalFieldManager hfm = new HorizontalFieldManager(Field.FIELD_HCENTER);
ButtonField lastWeek = new ButtonField("<<", ButtonField.CONSUME_CLICK);
lastWeek.setChangeListener(this);
ButtonField todayWeek = new ButtonField("Today", ButtonField.CONSUME_CLICK);
todayWeek.setChangeListener(this);
ButtonField nextWeek = new ButtonField(">>", ButtonField.CONSUME_CLICK);
nextWeek.setChangeListener(this);
hfm.add(lastWeek);hfm.add(todayWeek);hfm.add(nextWeek);
hfm.setPadding(10, 0, 10, 0);
VerticalFieldManager vfm = new VerticalFieldManager(Field.FIELD_VCENTER);
vfm.add(Monday);
vfm.add(MondayData);
vfm.add(Tuesday);
vfm.add(TuesdayData);
vfm.add(Wednesday);
vfm.add(WednesdayData);
vfm.add(Thursday);
vfm.add(ThursdayData);
vfm.add(Friday);
vfm.add(FridayData);
vfm.add(Saturday);
vfm.add(SaturdayData);
vfm.add(Sunday);
vfm.add(SundayData);
add(vfm);
add(new SeparatorField());
setTitle(title);
setBanner(banner);
setStatus(hfm);
}
public void fieldChanged(Field field, int context) {
if (field == lastWeek) {
lastTextFields();
}
else if (field == todayWeek) {
todayTextFields();
}
else if (field == nextWeek) {
nextTextFields();
}
}
private void lastTextFields() {
Monday.setText("Monday-old");
MondayData.setText("MondayData-old");
}
public void todayTextFields() {
//Monday.setText("Monday");
// MondayData.setText("MondayData");
Dialog.inform("Today pressed");
}
private void nextTextFields() {
Monday.setText("Monday-new");
MondayData.setText("MondayData-new");
}
}
Since you are running your application on 8520 device simulator that doesn't have touch screen, clicking on the buttons will get you nowhere. There are several options available:
Navigate to desired button by using one of the following methods:
Use the keyboard arrow keys to navigate. Press Enter to "click" on it.
Use your mouse's scroll wheel to navigate and then left click to "click".
Press F12 to turn "trackball mode" on and use your mouse navigate. Then either press Enter or right click when the desired button is selected.
Also check this Use the trackball and other Simulating BlackBerry device interaction manuals.
Alternatively, you can compile your application with JRE 6.0 or higher and pick a use a device simulator that supports touchscreen (9800 Torch, 9930 Bold and etc...).
EDIT
You are initiating local LabelFields and ButtonFields instead of the class' member variable. All class member variable remained uninitialized (e.g. equal null). You should remove the redundant local variable definitions.
Update all your LabelFields and ButtonFields in the following way:
LabelField banner = new LabelField("Diary", LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
ButtonField lastWeek = new ButtonField("<<", ButtonField.CONSUME_CLICK);

blackberry: problems getting focus of a field, if another field painted to same x coordinate

I have an AbsoluteFieldManager that contains several Fields in a horizontal row, switching the focus works fine. Now i need to add another Field on the same horizontal position as the left field above. When doing so, I can no more focus the first field. The screen should look as this:
________________________
| ____ ____ ____ |
| |_f1_| |_f2_| |_f3_| |
| ____ |
| |_f4_| | with f4 added here, f1 isn't focusable, once it has
|______________________| lost focus.
If you got any Ideas how to fix this, I'd apreciate. Here is my Code so far:
TestScreen:
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.container.AbsoluteFieldManager;
import net.rim.device.api.ui.container.MainScreen;
public class TestScreen extends MainScreen {
int screenY = Display.getWidth();
int screenX = Display.getHeight();
public TestScreen() {
AbsoluteFieldManager manager = new AbsoluteFieldManager();
TestField f1 = new TestField(50, 50, true);
TestField f2 = new TestField(50, 50, true);
TestField f3 = new TestField(50, 50, true);
TestField f4 = new TestField(50, 50, true);
TestField f5 = new TestField(50, 50, false);
manager.add(f1, 0, 0);
manager.add(f2, 60, 0);
manager.add(f3, 120, 0);
manager.add(f4, 180, 0);
// this works fine:
// manager.add(f5, 1, 80);
// this not:
manager.add(f5, 0, 80);
add(manager);
}
}
TestField:
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
public class TestField extends Field {
boolean isFocusable;
int width, height;
int bgColorUnfocused, bgColorFocused;
public TestField(int width, int height, boolean isFocusable){
this.width=width;
this.height=height;
this.isFocusable=isFocusable;
bgColorUnfocused= 0xC0C0C0;
bgColorFocused = 0x3956F7;
}
protected void layout(int w, int h) {
setExtent(width, height);
}
public boolean isFocusable() {
return isFocusable;
}
protected void paint(Graphics g) {
g.setColor(isFocus() ? bgColorFocused : bgColorUnfocused);
g.fillRect(0, 0, width, height);
}
}
TestApp:
import net.rim.device.api.ui.UiApplication;
public class TestApp extends UiApplication{
TestScreen screen = new TestScreen();
public static void main(String args[]){
TestApp app = new TestApp();
app.enterEventDispatcher();
}
public TestApp(){
pushScreen(screen);
}
}
Since AbsoluteFieldManager isn't really sure where you're placing items, it doesn't know what order to send focus when using the trackwheel. If you want to manage this, ovveride nextFocus(int, int) of the AFM so you can specify who gets the focus based off of where it is and where the intended movement is.
Take a look at http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Manager.html#nextFocus(int,%20int) for more details.

Control Horizontal Grid Line Visibility in DataGrid

I have a style requirement that my data grid show the horizontal grid lines every 3 rows...
Something like this:
-----------------------------------
one | two | three | four |
five | six | seven | eight |
nine | ten | eleven | twelve |
-----------------------------------
aaa | bbb | ccc | ddd |
eee | fff | ggg | hhh |
iii | jjj | kkk | lll |
-----------------------------------
mmm | nnn | ooo | ppp |
etc..
Does anyone know of an easy way of achieving this? I was considering updating the row style to include a border, and set the bottom border thickness to 1 every (x mod n) times, but this seems wrong.
There must be a better way?
So, after hacking away at it, I figured out a way. It is pretty nasty, but it works.
If I were in WPF, I would use the AlternationIndex and set a style trigger for index 0,1,2 and set the border thickness of index 2 to have a bottom index.
In Silverlight, we don't have AlternationIndex OR style triggers. So, I had to hack. I wrapped the code into a behavior, so my XAML is pretty clean:
Controls:DataGrid DataGridLines:HorizontalGridLineModulus.Index="3" ... />
The code to support it looks like this:
public static class HorizontalGridLineModulus
{
private static readonly DependencyProperty HorizontalGridLineModulusBehaviorProperty =
DependencyProperty.RegisterAttached(
"HorizontalGridLineModulusBehavior",
typeof (HorizontalGridLineModulusBehavior),
typeof (DataGrid),
null);
public static readonly DependencyProperty IndexProperty =
DependencyProperty.RegisterAttached(
"Index",
typeof (int),
typeof (HorizontalGridLineModulus),
new PropertyMetadata(1, IndexChanged)
);
public static int GetIndex(DependencyObject dependencyObject)
{
return (int)dependencyObject.GetValue(IndexProperty);
}
public static void SetIndex(DependencyObject dependencyObject, int value)
{
dependencyObject.SetValue(IndexProperty, value);
}
private static void IndexChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var behavior = dependencyObject.GetValue(HorizontalGridLineModulusBehaviorProperty) as HorizontalGridLineModulusBehavior;
if (behavior == null)
{
behavior = new HorizontalGridLineModulusBehavior(dependencyObject as DataGrid, (int)e.NewValue);
dependencyObject.SetValue(HorizontalGridLineModulusBehaviorProperty, behavior);
}
}
}
public class HorizontalGridLineModulusBehavior
{
private readonly DataGrid _grid;
private readonly int _modulus;
public HorizontalGridLineModulusBehavior(DataGrid grid, int modulus)
{
if(grid == null)
throw new ArgumentException("grid");
_grid = grid;
_modulus = modulus;
_grid.LayoutUpdated += GridLayoutUpdated;
}
private void GridLayoutUpdated(object sender, EventArgs e)
{
DrawBorders();
}
private void DrawBorders()
{
var presenter = _grid.Descendants<DataGridRowsPresenter>().FirstOrDefault();
if(presenter == null) return;
var orderedRows = presenter.Children.OrderBy(child => RowIndex(child));
int count = 0;
foreach (var row in orderedRows)
{
count++;
var gridLine = row.Descendants<Rectangle>().Where(x => x.Name == "BottomGridLine").FirstOrDefault();
if(gridLine != null)
gridLine.Visibility = count % _modulus != 0 ? Visibility.Collapsed : Visibility.Visible;
}
}
private static int RowIndex(UIElement element)
{
var row = element as DataGridRow;
return row == null ? 0 : row.GetIndex();
}
}
That code makes use of a few extension methods, defined here:
public static class DependencyObjectExtensions
{
public static IEnumerable<DependencyObject> Children(this DependencyObject element)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
yield return VisualTreeHelper.GetChild(element, i);
}
public static IEnumerable<T> Children<T>(this DependencyObject element) where T : DependencyObject
{
return element.Children().Filter<T>();
}
public static IEnumerable<DependencyObject> Descendants(this DependencyObject element)
{
foreach (var child in element.Children())
{
yield return child;
foreach (var descendent in child.Descendants())
yield return descendent;
}
}
public static IEnumerable<T> Descendants<T>(this DependencyObject element) where T : DependencyObject
{
return element.Descendants().Filter<T>();
}
public static IEnumerable<T> Filter<T>(this IEnumerable list) where T : class
{
foreach (var item in list)
{
if (item is T)
yield return (T)item;
}
}
}

Resources