Может ли свойство snapToPixel повлиять на поведение моего макета элемента управления?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Может ли свойство snapToPixel повлиять на поведение моего макета элемента управления?

Сообщение Anonymous »

В классе Region у нас есть свойство snapToPixel, которое предназначено для привязки/округления значений пикселей границ для достижения четкого пользовательского интерфейса (как указано в javadoc). >
Но предполагается ли, что переключение значения этого свойства может повлиять на поведение основного макета? По крайней мере, для стандартных элементов управления?
Проблема:
В сценариях, когда ширина TableRow на 1 пиксель больше ширины VirtualFlow, отображается горизонтальная полоса прокрутки VirtualFlow. Это действительно так, и я с этим согласен (как показано на скриншоте ниже). На рисунке ниже ширина VirtualFlow составляет 307 пикселей, а ширина TableRow – 308 пикселей.
[img]https: //i.sstatic.net/LPH0Ukdr.png[/img]

В приведенном выше сценарии, когда я перетаскиваю ползунок полосы прокрутки, я ожидаю перемещения TableRow на один пиксель. Но этого не происходит. На самом деле, когда я перетаскиваю ползунок, ничего не происходит (ни содержимое не перемещается, ни сам ползунок).
При тщательном исследовании выяснилось, что ширина дорожки полосы прокрутки такая же, как у ширину большого пальца, что приводит к игнорированию события перетаскивания.
Ниже приведен код события перетаскивания большого пальца в классе ScrollBarSkin, где вы можете заметить условие if, позволяющее пропустить вычисления. если длина большого пальца не меньше длины дорожки.
thumb.setOnMouseDragged(me -> {
if (me.isSynthesized()) {
// touch-screen events handled by Scroll handler
me.consume();
return;
}
/*
** if max isn't greater than min then there is nothing to do here
*/
if (getSkinnable().getMax() > getSkinnable().getMin()) {
/*
** if the tracklength isn't greater then do nothing....
*/
if (trackLength > thumbLength) {
Point2D cur = thumb.localToParent(me.getX(), me.getY());
if (dragStart == null) {
// we're getting dragged without getting a mouse press
dragStart = thumb.localToParent(me.getX(), me.getY());
}
double dragPos = getSkinnable().getOrientation() == Orientation.VERTICAL ? cur.getY() - dragStart.getY(): cur.getX() - dragStart.getX();
behavior.thumbDragged(preDragThumbPos + dragPos / (trackLength - thumbLength));
}

me.consume();
}
});

Теперь, когда я дальше исследую, почему длины дорожки и ползунка одинаковы, я заметил, что на самом деле это код вычисления длины ползунка, который фиксирует вычисленное значение.
thumbLength = snapSizeX(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));

В приведенной выше строке вычисленное значение trackLength составляет 289,0 пикселей, а вычисленное значение ThumbLength – 288,06168831168833 пикселей. Но поскольку это значение привязано, оно округляется до 289,0 пикселей, что равно trackLength.
Решение/обходное решение:
Из приведенного выше наблюдения видно, что свойство snapToPixel элемента ScrollBar влияет на вычисленные значения. Поэтому я создал собственный VirtualFlow для доступа к полосам прокрутки и отключения свойства snapToPixel.
class CustomVirtualFlow extends VirtualFlow {
public CustomVirtualFlow() {
getHbar().setSnapToPixel(false);
getVbar().setSnapToPixel(false);
}
}

Как только я включил эту настройку, полоса прокрутки стала активной, и когда я перетаскиваю большой палец, он перемещает мой контент. Вы можете заметить разницу на рисунке ниже.
Изображение

Итак, мой вопрос: является ли это предполагаемым поведением, имеющим snapToPixel=true по умолчанию, что приводит к ненужному отображению полосы прокрутки, и я обязан отключить свойства snapToPixel? Другими словами, это ошибка JavaFX или нет?
Ниже приведен демонстрационный код:
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.skin.TableViewSkin;
import javafx.scene.control.skin.VirtualFlow;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;

public class HorizontalScrollBarIssueDemo extends Application {

String CSS = "data:text/css," +
"""
.label{
-fx-font-weight: bold;
}
""";

@Override
public void start(final Stage stage) throws Exception {
final VBox root = new VBox();
root.setSpacing(30);
root.setPadding(new Insets(10));
final Scene scene = new Scene(root, 500, 350);
scene.getStylesheets().add(CSS);
stage.setScene(scene);
stage.setTitle("Horizontal ScrollBar Issue " + System.getProperty("javafx.runtime.version"));
stage.show();

VBox defaultBox = new VBox(10, new Label("Default TableView"), getTable(false));
VBox customBox = new VBox(10, new Label("TableView whose scrollbar's snapToPixel=false"), getTable(true));
root.getChildren().addAll(defaultBox, customBox);
}

private TableView getTable(boolean custom) {
TableView tableView;
if (custom) {
tableView = new TableView() {
@Override
protected Skin createDefaultSkin() {
return new TableViewSkin(this) {
@Override
protected VirtualFlow createVirtualFlow() {
return new CustomVirtualFlow();
}
};
}
};
} else {
tableView = new TableView();
}
tableView.setMaxHeight(98);
tableView.setMaxWidth(309);
VBox.setVgrow(tableView, Priority.ALWAYS);
int colCount = 4;
for (int i = 0; i < colCount; i++) {
final int index = i;
TableColumn column = new TableColumn("Option " + i);
column.setCellValueFactory(param -> new ReadOnlyObjectWrapper(param.getValue().get(index)));
tableView.getColumns().add(column);
}
for (int j = 0; j < 1; j++) {
List row = new ArrayList();
for (int i = 0; i < colCount; i++) {
row.add("Row" + j + "-Opt" + i);
}
tableView.getItems().add(row);
}

return tableView;
}

class CustomVirtualFlow extends VirtualFlow {
public CustomVirtualFlow() {
getHbar().setSnapToPixel(false);
getVbar().setSnapToPixel(false);
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/790 ... -behaviour
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»