RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 588710
Accepted
HideDJeker
HideDJeker
Asked:2020-11-09 12:24:22 +0000 UTC2020-11-09 12:24:22 +0000 UTC 2020-11-09 12:24:22 +0000 UTC

GUI java.swing 使用什么组件

  • 772

如何在其他组件之上添加组件?如何对齐它们?

问题出在小组的组织上,也许我会尝试解释一下情况。总的来说,我的任务是组织一个用于数列运算的计算器,你不需要了解它是什么以及它们是如何计算的,你唯一需要知道的是它们的解不是通过等号,而是通过实线在一个专栏中,向上。首先写出原始方程(数列),然后通过用户选择的某个公式,将变换后的公式(数列)写在最上面,当每一列都在最上面的“|”两边时,就认为问题解决了。 -”标志(同理)。

难点在于,借助于这些转换,示例往往被分成 2 个,甚至 3 个,变成单独的子任务,每个子任务都需要解决(即,它们可以依次划分,直到用户达到所需的步骤)。

如何在其他组件之上添加组件?怎么对齐?(在线上可以有3个组件,在同一水平线上,比如左边也有3个组件,左边的可以把右边的推出去它们的位置并且很难理解它们与哪个子组件相关,为此有必要以某种方式对齐低一级的所有组件?)而且我需要实现对这些位于顶层的组件的选择在他们的列中,以便将来选择公式并执行将写入上面级别的转换。

对任何实现感兴趣,无论它是什么曲线。对于此事,我将不胜感激。

解决方案

java
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Dmitriy
    2020-11-09T18:50:14Z2020-11-09T18:50:14Z

    1 个选项。Swing 知道 HTML,这可能是最快和最简单的方法。
    选项 2。动作如下,有条件地想象图形表示可以分成单元格。
    我们会将单元格限制为只能在其中放置 2 或 1 个组件的可能性。
    单元格中的组件只能水平(左和右)或垂直(顶部和底部)或不拆分。
    现在,按照上述规则,我们得到以下内容(根据您提供的图片中的数字):
    Start(1)将是一个垂直的 2 组件单元格。单组件单元格放置在我们放置文本的“底部”。
    在“顶部”,我们放置了一个水平的 2 组件单元格。在“左”和“右”中,我们放置了一个垂直的 2 分量单元格。
    现在,在“底部”的每个单元格中,我们放置一个带有文本(2) 的单组件单元格。在顶部,我们可以继续压缩单元格或插入文本end(3)。
    原来是“俄罗斯套娃”。如果在步骤(2)中有必要有 3-4-5 个块,那么我们将用水平单元(彼此)扩展它们。

    • 2
  2. Best Answer
    zRrr
    2020-11-10T03:47:03Z2020-11-10T03:47:03Z

    您可以使用GridBagLayout - 这是一个具有“橡胶”大小的行和列的网格,其中一个组件可以占据多个单元格。这种解决方案的优点是在不同的计算分支中高度对齐行。缺点:换树时需要自己重新计算组件在网格上的大小和位置,将无法简单实现部分计算的折叠。

    实现示例:

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.Line2D;
    import java.util.*;
    import java.util.List;
    
    import javax.swing.*;
    import javax.swing.border.StrokeBorder;
    
    
    public class GridBagTreeDisplay {
    
        static class TopLineBorder extends StrokeBorder {
            private static final long serialVersionUID = 819507837355280534L;
    
            public TopLineBorder(BasicStroke stroke) {
                super(stroke);
            }
    
            @Override
            public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
                float size = this.getStroke().getLineWidth();
                Graphics2D g2d = (Graphics2D)g.create();
                g2d.setStroke(this.getStroke());
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.draw( new Line2D.Float( x + size / 2, y + size / 2, width - size, y + size / 2 ) );
                g2d.dispose();
            }
        }
    
        /**
         * Класс, поддерживающий древовидное отображение с помощью GridBagLayout
         * 
         * Манипуляции с узлами дерева осуществляются непосредственно с экземплярами
         * класса TreeView.TreeNode.
         * 
         * Для отображения изменений нужно вызвать метод update()
         */
        static class TreeView {
            private Container container;
    
            private TreeNode root;
    
            public TreeView( Container container ) {
                this.container = container;
                this.container.setLayout( new GridBagLayout() );
            }
    
            public void update() {
                container.removeAll();
    
                if ( root != null ) {
                    root.computeAll( 0 );
                    root.layoutComponentsOn( container );
                }
    
                container.revalidate();
                container.repaint();
            }
    
            public void setRootComponent( JComponent rootComponent ) {
                Objects.requireNonNull( rootComponent );
                this.root = new TreeNode( null, rootComponent );
            }
    
            public TreeNode root() {
                return root;
            }
    
            public Optional<TreeNode> findNodeByComponent( JComponent componentToFind ) {
                return root.findByComponent( componentToFind );
            }
    
            class TreeNode {
                private JComponent component;
    
                private int position;
                private int depth;
    
                private int width;
                private int height;
    
                private TreeNode parent;
                private List<TreeNode> children = new ArrayList<>();
    
                TreeNode( TreeNode parent, JComponent component ) {
                    this.parent = parent;
                    this.component = component;
    
                    this.depth = parent != null ? parent.depth + 1 : 0;
                }
    
                /**
                 * Обновляет высоту и ширину поддерева с корнем в этом узле,
                 * рекурсивно обновляя высоту и ширину для поддеревьев
                 */
                private void computeSize() {
                    if ( children.isEmpty() ) {
                        width = 1;
                        height = 1;
                    } else {
                        int sumChildWidth = 0;
                        int maxChildHeight = 0;
                        for ( TreeNode child : children ) {
                            child.computeSize();
    
                            sumChildWidth += child.width;
                            maxChildHeight = Math.max( maxChildHeight, child.height );
                        }
                        width = sumChildWidth;
                        height = maxChildHeight + 1;
                    }
                }
    
                /**
                 * Устанавливает горизонтальную позицию этого узла в сетке
                 * и обновляет позиции в поддеревьях
                 * 
                 * @param newPosition - новая позиция
                 */
                private void computePosition( int newPosition ) {
                    this.position = newPosition;
    
                    int childLeft = position;
                    for ( TreeNode child : children ) {
                         child.computePosition( childLeft );
                         childLeft += child.width; 
                    }
                }
    
                /**
                 * обновляет размеры и горизонтальную позицию узла и
                 * его поддеревьев
                 * 
                 * @param newPosition
                 */
                private void computeAll( int newPosition ) {
                    computeSize();
    
                    computePosition( newPosition );
                }
    
                public void updateTreeView() {
                    TreeView.this.update();
                }
    
                /**
                 * Заменяет текущих детей этого узла на новые,
                 * содержащие переданные компоненты
                 * 
                 * @param components
                 */
                public void setChildren( JComponent... components ) {
                    children.clear();
                    for ( JComponent component : components ) {
                        children.add( new TreeNode( this, component ) );
                    }
                }
    
                public TreeNode parent() {
                    return parent;
                }
    
                public List<TreeNode> children() {
                    return Collections.unmodifiableList( children );
                }
    
                public JComponent component() {
                    return component;
                }
    
                public TreeView treeView() {
                    return TreeView.this;
                }
    
                public Optional<TreeNode> findByComponent( JComponent componentToFind ) {
                    if ( this.component == componentToFind ) {
                        return Optional.of( this );
                    }
    
                    for ( TreeNode child : children ) {
                        Optional<TreeNode> found = child.findByComponent( componentToFind );
                        if ( found.isPresent() ) return found;
                    }
    
                    return Optional.empty();
                }
    
                /**
                 * Размещает компоненты текущего узла и дочерних узлов в
                 * переданном контейнере
                 * 
                 * @param container
                 */
                private void layoutComponentsOn( Container container ) {
                    if ( !(container.getLayout() instanceof GridBagLayout ) ) {
                        throw new IllegalArgumentException( "container must use GridBagLayout" );
                    }
                    layoutComponentsOnRecursive( container, this.height );
                }
    
                private void layoutComponentsOnRecursive( Container container, int treeHeight ) {
                    // параметры размещения компонента:
                    GridBagConstraints gbc = new GridBagConstraints( 
                            position,                      // позиция по горизонтали
                            treeHeight - depth,            // позиция по вертикали
                            width,                         // число ячеек по ширине
                            1,                             // число ячеек по высоте
                            1.0,                           // вес компонента по ширине, при ненулевом весе GridBagLayout
                                                           // постарается занять всю ширину контейнера
                            0,                             // вес по высоте
                            GridBagConstraints.CENTER,     // компонент располагается в центре своей области
                            GridBagConstraints.HORIZONTAL, // и растягивается по горизонтали
                            new Insets( 2, 5, 2, 5 ),      // отступы от краев области
                            0, 0                           // минимальные ширина и высота
                        );
    
                    // компонентам из узлов с детьми устанавливаем границу с линией
                    component.setBorder( !children.isEmpty() ? new TopLineBorder( new BasicStroke( 1.0f ) ) : null );
    
                    container.add( component, gbc );
    
                    for ( TreeNode child : children ) {
                        child.layoutComponentsOnRecursive( container, treeHeight );
                    }
                }
            }
        }
    
        static JLabel[] makeClickableLabels( TreeView display, String... captions ) {
            JLabel[] labels = Arrays.stream( captions )
                    .map( caption -> new JLabel( caption, SwingConstants.CENTER ) )
                    .toArray( JLabel[]::new );
    
            for ( JLabel label : labels ) {
                label.addMouseListener( new MouseAdapter() {
                    @Override public void mouseClicked( MouseEvent event ) {
                        display.findNodeByComponent( (JComponent)event.getComponent() )
                            .ifPresent( node -> {
                                if ( event.isShiftDown() ) {
                                    node.setChildren();
                                } else {
                                    node.setChildren( makeClickableLabels( display, "left", "center", "right" ) );
                                }
                                display.update();
                            });
                    }
                });
            }
    
            return labels;
        }
    
        static void initUi() {
            JFrame frame = new JFrame( "" );
            frame.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
    
            JPanel content = new JPanel();
    
            TreeView treeView = new TreeView( content );
    
            treeView.setRootComponent( makeClickableLabels( treeView, "root" )[0] );
    
            TreeView.TreeNode root = treeView.root();
            root.setChildren( makeClickableLabels( treeView, "1-left", "1-right" ) );
    
            root.children().get( 0 ).setChildren( makeClickableLabels( treeView, "2-left-left", "2-left-center", "2-left-right" ) );
            root.children().get( 1 ).setChildren( makeClickableLabels( treeView, "2-right-center" ) );
    
            root.children().get( 1 ).children().get( 0 ).setChildren( makeClickableLabels( treeView, "3-right-center-center" ) );
    
            root.updateTreeView();
    
            frame.add( content, BorderLayout.CENTER );
    
            frame.setSize( 800, 600 );
            frame.setVisible( true );
        }
    
    
    
        public static void main(String[] args) {
            EventQueue.invokeLater( GridBagTreeDisplay::initUi );
        }
    
    }
    

    结果:

    工作范例

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5