scala swing:可拖动/可调整大小的组件特征

发布于 2024-11-03 03:27:46 字数 220 浏览 1 评论 0 原文

我正在寻找一个可以混合到 scala.swing.Component 中的 scala 特征,该特征将允许使用鼠标输入来定位该组件并调整其大小。

理想情况下,它会添加小框作为“句柄”,以向用户指示该组件可以调整大小: 在此处输入图像描述

我觉得这是一项相当常见的任务,并且应该有一些特征支持它。

I'm looking for a scala trait that I can mix in to a scala.swing.Component that will allow that component to be positioned and resized using mouse input.

Ideally it would add little boxes as "handles" to indicate to the user that the component can be resized:
enter image description here

I feel like this is a fairly common task, and there should be some traits out there that support it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我三岁 2024-11-10 03:27:46

我在当前的项目中使用这些。您可能需要用自己的矢量库替换矢量库并添加隐式定义。或者使用 swing 中的点/尺寸。组件需要位于允许自定义位置和大小的面板中,例如 http://dgronau.wordpress.com/2010/08/28/eine-frage-des-layouts/

trait Movable extends Component{
    var dragstart:Vec2i = null
    listenTo(mouse.clicks, mouse.moves)
    reactions += {
        case e:MouseDragged =>
            if( dragstart != null )
                peer.setLocation(location - dragstart + e.point)
        case e:MousePressed =>
            this match {
                case component:Resizable =>
                    if( component.resizestart == null )
                        dragstart = e.point
                case _ =>
                    dragstart = e.point
                     
            }
        case e:MouseReleased =>
            dragstart = null    
    }
}

trait Resizable extends Component{
    var resizestart:Vec2i = null
    var oldsize = Vec2i(0)
    def resized(delta:Vec2i) {}
    listenTo(mouse.clicks, mouse.moves)
    reactions += {
        case e:MouseDragged =>
            if( resizestart != null ){
                val delta = e.point - resizestart
                peer.setSize(max(oldsize + delta, minimumSize))

                oldsize += delta
                resizestart += delta

                resized(delta)
                revalidate
            }
        case e:MousePressed =>
            if( size.width - e.point.x < 15
             && size.height - e.point.y < 15 ){
                resizestart = e.point
                oldsize = size
            
                this match {
                    case component:Movable =>
                        component.dragstart = null
                    case _ =>
                }
            }
        case e:MouseReleased =>
            resizestart = null
    }
}

I'm using these in my current project. You probably need to replace the Vector library with your own and add implicit defs. Or use Point/Dimension from swing. The Components need to be in a panel which allows custom positions and sizes, like NullPanel from http://dgronau.wordpress.com/2010/08/28/eine-frage-des-layouts/

trait Movable extends Component{
    var dragstart:Vec2i = null
    listenTo(mouse.clicks, mouse.moves)
    reactions += {
        case e:MouseDragged =>
            if( dragstart != null )
                peer.setLocation(location - dragstart + e.point)
        case e:MousePressed =>
            this match {
                case component:Resizable =>
                    if( component.resizestart == null )
                        dragstart = e.point
                case _ =>
                    dragstart = e.point
                     
            }
        case e:MouseReleased =>
            dragstart = null    
    }
}

trait Resizable extends Component{
    var resizestart:Vec2i = null
    var oldsize = Vec2i(0)
    def resized(delta:Vec2i) {}
    listenTo(mouse.clicks, mouse.moves)
    reactions += {
        case e:MouseDragged =>
            if( resizestart != null ){
                val delta = e.point - resizestart
                peer.setSize(max(oldsize + delta, minimumSize))

                oldsize += delta
                resizestart += delta

                resized(delta)
                revalidate
            }
        case e:MousePressed =>
            if( size.width - e.point.x < 15
             && size.height - e.point.y < 15 ){
                resizestart = e.point
                oldsize = size
            
                this match {
                    case component:Movable =>
                        component.dragstart = null
                    case _ =>
                }
            }
        case e:MouseReleased =>
            resizestart = null
    }
}
她如夕阳 2024-11-10 03:27:46

我所知道的唯一可拖动且可调整大小的组件是 JDesktop 上的 InternalFrame。这里有一个例子:

import swing._
import event._

import javax.swing.{UIManager,JComponent}
import javax.swing.KeyStroke.getKeyStroke
import java.awt.{Graphics2D,Graphics}

object InternalFrameDemo extends SimpleSwingApplication{
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName)

    val top = new MainFrame{
        title = "InternalFrameDemo"
        preferredSize = new Dimension(640,480)
        val desktop = new javax.swing.JDesktopPane

        val jc = new JComponent{
            override def paint(g:Graphics){
                import g._
                drawLine(0,0,20,20)
                drawLine(0,20,20,0)
                println("yay draw")
            }

            setVisible(true)
        }

        desktop add jc

        contents = Component.wrap(desktop)

        menuBar = new MenuBar{
            contents += new Menu("Document"){
                mnemonic = Key.D

                contents += new MenuItem("New"){
                    mnemonic = Key.N
                    action = new Action("new"){
                        def apply = createFrame
                        accelerator = Some(getKeyStroke("alt N"))
                    }
                }

                contents += new MenuItem("Quit"){
                    mnemonic = Key.Q
                    action = new Action("quit"){
                        def apply(){
                            quit()
                        }
                        accelerator = Some(getKeyStroke("alt Q"))
                    }
                }
            }
        }

        def createFrame{
            val newFrame = MyInternalFrame()
            newFrame setVisible true
            desktop add newFrame
            newFrame setSelected true

        }
    }
}

import javax.swing.{JDesktopPane,JInternalFrame}
import collection.mutable.ArrayBuffer

object MyInternalFrame{
    var openFrameCount = 0;
    val xOffset, yOffset = 30;

    def apply() = {
        openFrameCount += 1
        val jframe = new javax.swing.JInternalFrame("Document #" + openFrameCount,true,true,true,true)

        jframe.setSize(300,300)
        jframe.setLocation(xOffset*openFrameCount,yOffset*openFrameCount)

        jframe //Component.wrap(jframe)
    }
}

但是JInternalFrame和JDesktop都没有集成在scala swing包中,需要手动包装。

The only Component I know of that is Dragable and resizeable is the InternalFrame on the JDesktop. here is an example:

import swing._
import event._

import javax.swing.{UIManager,JComponent}
import javax.swing.KeyStroke.getKeyStroke
import java.awt.{Graphics2D,Graphics}

object InternalFrameDemo extends SimpleSwingApplication{
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName)

    val top = new MainFrame{
        title = "InternalFrameDemo"
        preferredSize = new Dimension(640,480)
        val desktop = new javax.swing.JDesktopPane

        val jc = new JComponent{
            override def paint(g:Graphics){
                import g._
                drawLine(0,0,20,20)
                drawLine(0,20,20,0)
                println("yay draw")
            }

            setVisible(true)
        }

        desktop add jc

        contents = Component.wrap(desktop)

        menuBar = new MenuBar{
            contents += new Menu("Document"){
                mnemonic = Key.D

                contents += new MenuItem("New"){
                    mnemonic = Key.N
                    action = new Action("new"){
                        def apply = createFrame
                        accelerator = Some(getKeyStroke("alt N"))
                    }
                }

                contents += new MenuItem("Quit"){
                    mnemonic = Key.Q
                    action = new Action("quit"){
                        def apply(){
                            quit()
                        }
                        accelerator = Some(getKeyStroke("alt Q"))
                    }
                }
            }
        }

        def createFrame{
            val newFrame = MyInternalFrame()
            newFrame setVisible true
            desktop add newFrame
            newFrame setSelected true

        }
    }
}

import javax.swing.{JDesktopPane,JInternalFrame}
import collection.mutable.ArrayBuffer

object MyInternalFrame{
    var openFrameCount = 0;
    val xOffset, yOffset = 30;

    def apply() = {
        openFrameCount += 1
        val jframe = new javax.swing.JInternalFrame("Document #" + openFrameCount,true,true,true,true)

        jframe.setSize(300,300)
        jframe.setLocation(xOffset*openFrameCount,yOffset*openFrameCount)

        jframe //Component.wrap(jframe)
    }
}

but both JInternalFrame and JDesktop are not integrated in the scala swing package and need to be wrapped manually.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文