简体   繁体   English

使用JLabel显示计数吗?

[英]Displaying a count using JLabel?

My project has classes Car and Truck that inherit from abstract class Vehicle . 我的项目有从abstract class Vehicle继承的CarTruck abstract class Vehicle Then at random a car or vehicle is to be drawn a total of 10 times. 然后,随机抽取汽车或车辆总共10次。 Also, a count of how many of each is to be displayed in a JLabel , but my counts keep showing up as 0 in the JFrame . 另外,在JLabel中将显示每个计数的计数,但是我的计数在JFrame始终显示为0。 Here is my code. 这是我的代码。

package vehiclePackage;

import java.awt.Graphics;
import java.util.Random;

public abstract class Vehicle 
{
    public Vehicle() {
    }

    public Vehicle(int xLeft, int yTop) { 
    }

    public abstract void draw(Graphics g2);
}

Car Class: Car类:

package vehiclePackage;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Random;

public class Car extends Vehicle
{
    private int xLeft;
    private int yTop;
    private int ccount;

    public Car() { }

    public Car (int x, int y)
    {
        super(x,y);
        this.xLeft = x;
        this.yTop = y;
    }

    //@override
    public void draw(Graphics g2)
    {

        Random rand = new Random();

        float red = rand.nextFloat();
        float green = rand.nextFloat();
        float blue = rand.nextFloat();

         Color randomColor = new Color(red, green, blue);

        Rectangle body = new Rectangle (xLeft, yTop +10, 60, 10);
        Ellipse2D.Double frontTire = new Ellipse2D.Double (xLeft+10, yTop+20, 10, 10);
        Ellipse2D.Double rearTire = new Ellipse2D.Double (xLeft+40, yTop+20, 10, 10);

        Point2D.Double r1 = new Point2D.Double(xLeft+10, yTop+10);
        Point2D.Double r2 = new Point2D.Double(xLeft+20, yTop);
        Point2D.Double r3 = new Point2D.Double(xLeft+40, yTop);
        Point2D.Double r4 = new Point2D.Double(xLeft+50, yTop+10);

        Line2D.Double frontWindshield = new Line2D.Double(r1,r2);
        Line2D.Double roofTop = new Line2D.Double(r2,r3);
        Line2D.Double rearWindshield = new Line2D.Double(r3,r4);

        ((Graphics2D) g2).setColor(randomColor);

        ((Graphics2D) g2).fill(body);
        ((Graphics2D) g2).fill(frontTire);
        ((Graphics2D) g2).fill(rearTire);

        ((Graphics2D) g2).draw(body);
        ((Graphics2D) g2).draw(frontTire);
        ((Graphics2D) g2).draw(rearTire);
        ((Graphics2D) g2).draw(frontWindshield);
        ((Graphics2D) g2).draw(rearWindshield);
        ((Graphics2D) g2).draw(roofTop);

    }   
}

Truck Class: Truck类别:

package vehiclePackage;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.util.Random;

public class Truck extends Vehicle
{
    private int xLeft;
    private int yTop;
    private int tcount;

    public Truck()
    {

    }
    public Truck (int x, int y)
    {
        super(x, y);
        this.xLeft = x;
        this.yTop = y;
    }

    public void draw(Graphics g2)
    {
        Random rand = new Random();

        float red = rand.nextFloat();
        float green = rand.nextFloat();
        float blue = rand.nextFloat();

         Color randomColor = new Color(red, green, blue);

        Rectangle body = new Rectangle (xLeft + 22, yTop +10, 60, 20);
        Rectangle topCab = new Rectangle(xLeft, yTop + 10, 20, 10);
        Rectangle bottomCab = new Rectangle(xLeft, yTop + 20, 20, 10);
        Ellipse2D.Double frontTire = new Ellipse2D.Double (xLeft+6, yTop+30, 10, 10);
        Ellipse2D.Double midTire = new Ellipse2D.Double (xLeft+25, yTop+30, 10, 10);
        Ellipse2D.Double mid2Tire = new Ellipse2D.Double (xLeft+35, yTop+30, 10, 10);
        Ellipse2D.Double backTire = new Ellipse2D.Double (xLeft+55, yTop+30, 10, 10);
        Ellipse2D.Double back2Tire = new Ellipse2D.Double (xLeft+65, yTop+30, 10, 10);

        ((Graphics2D) g2).setColor(randomColor);

        ((Graphics2D) g2).fill(body);
        ((Graphics2D) g2).fill(bottomCab);
        ((Graphics2D) g2).fill(frontTire);
        ((Graphics2D) g2).fill(midTire);
        ((Graphics2D) g2).fill(mid2Tire);
        ((Graphics2D) g2).fill(backTire);
        ((Graphics2D) g2).fill(back2Tire);

        ((Graphics2D) g2).draw(body);
        ((Graphics2D) g2).draw(topCab);
        ((Graphics2D) g2).draw(bottomCab);
        ((Graphics2D) g2).draw(frontTire);
        ((Graphics2D) g2).draw(midTire);
        ((Graphics2D) g2).draw(mid2Tire);
        ((Graphics2D) g2).draw(backTire);
        ((Graphics2D) g2).draw(back2Tire);
    }
}

VehicleComponent Class: VehicleComponent类别:

package vehiclePackage;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;

import javax.swing.JComponent;

public class VehicleComponent extends JComponent
{
    private int x;
    private int y;

    private static int ccount = 0;
    private static int tcount = 0;


    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;


        Random rand = new Random();

        for (int i = 1; i<=10; i ++)
        {

            int vehic = rand.nextInt(2);
            if (vehic == 0)
            {
                x = rand.nextInt(420);
                y = rand.nextInt(545);

                Vehicle car = new Car(x, y);
                car.draw(g2);
                ccount += 1;
            }
            if (vehic ==1)
            {
                x = rand.nextInt(420);
                y = rand.nextInt(545);
                Vehicle truck = new Truck(x, y);
                truck.draw(g2);
                tcount += 1;

            }
        }
    }
    public String toString()
    {
        return "Trucks: " + tcount + ", Cars: " + ccount;
    }
}

VehicleTester : VehicleTester

package vehiclePackage;

import java.awt.BorderLayout;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class VehicleViewer {

    public static void main(String[] args) 
    {
        // TODO Auto-generated method stub
        JFrame f = new JFrame();

        f.setSize(500,600);
        f.setTitle("Cars and Trucks");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        VehicleComponent component = new VehicleComponent();
        f.add(component);
        JLabel runningCount = new JLabel(component.toString());
        f.add(runningCount, BorderLayout.SOUTH);

        f.setVisible(true);
    }
}

Your problem is you're computing the value for the label text before the paintComponent routine has been called. 您的问题是您在调用paintComponent例程之前正在计算标签文本的值。 Once it's called, the text is left with the old value. 调用后,文本将保留旧值。

My suggested edit would be to move the figuring of which vehicle to be drawn to the constructor for VehicleComponent and then when it comes time to draw them, you can look in a pre-populated array to determine what should be drawn, and the counts will already be updated. 我建议的编辑是将要绘制的车辆的图移到VehicleComponent的构造函数中,然后到绘制它们的时间时,您可以查看一个预先填充的数组以确定应该绘制的内容,然后计数已经更新。

See the updates for VehicleComponent 查看VehicleComponent的更新

public class VehicleComponent extends JComponent
{
    private int x;
    private int y;

    private int ccount = 0;    // these shouldn't be static
    private int tcount = 0;   

    private boolean[] truckOrCar; // simple boolean array (you can change the type as you add more vehicles...)

    public VehicleComponent() {
        // figure out your car/truck count here
        Random rand = new Random();
        truckOrCar = new boolean[10];

        for (int i = 0; i<10; i ++)
        {
            int vehic = rand.nextInt(2);
            if (vehic == 0)
            {
                // false for car
                truckOrCar[i] = false;
                ccount += 1;
            }
            else {
                // true for truck
                truckOrCar[i] = true;
                tcount += 1;
            }
        }
    }

    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;

        Random rand = new Random();

        // here just look in your list for what to draw
        for (int i = 0; i<10; i ++)
        {

            // false for car
            if ( !truckOrCar[i] )
            {
                x = rand.nextInt(420);
                y = rand.nextInt(545);

                Vehicle car = new Car(x, y);
                car.draw(g2);
                ccount += 1;
            }
            // true for truck
            else
            {
                x = rand.nextInt(420);
                y = rand.nextInt(545);
                Vehicle truck = new Truck(x, y);
                truck.draw(g2);
                tcount += 1;
            }
        }
    }

    public String toString()
    {
        return "Trucks: " + tcount + ", Cars: " + ccount;
    }

}

See result (though your paint coordinates are a little off...): 查看结果(尽管您的绘制坐标有些偏离...):

在此处输入图片说明

What I think you're not understanding is how painting actually works in Swing. 我想您不了解的是绘画在Swing中的实际工作方式。 Painting is destructive, that is, each time your component is painted, it is expected to completely repaint its entire state, from scratch... 绘制是破坏性的,也就是说,每次绘制组件时,都希望从头开始完全重新绘制其整个状态。

Take a look at Performing Custom Painting and Painting in AWT and Swing for more details... 看一下在AWT和Swing执行自定义绘画绘画以获取更多详细信息...

So you loops in your paintComponent method, will, if you're really lucky, only ever paint a single vehicle. 因此,您循环使用paintComponent方法,如果真的很幸运的话,将只绘制单个车辆。

Instead, you need to maintain the vehicles in some kind of List or array and simply let paintComponent paint the lists... 取而代之的是,您需要将车辆保持在某种类型的List或数组中,并只需用paintComponent绘制列表即可。

So, we could change VehicleComponent thus... 因此,我们可以更改VehicleComponent从而...

public class VehicleComponent extends JComponent {

    private List<Car> cars;
    private List<Truck> trucks;

    private Random rnd = new Random();

    public VehicleComponent() {
        cars = new ArrayList<>(25);
        trucks = new ArrayList<>(25);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        for (Car car : cars) {
            car.draw(g2);
        }
        for (Truck truck : trucks) {
            truck.draw(g2);
        }
    }

    @Override
    public String toString() {
        return "Trucks: " + trucks.size() + ", Cars: " + cars.size();
    }

}

This will now simply paint whatever is in the cars and trucks lists when ever the component is repainted... 现在,只要重新喷涂零部件,它就可以简单地喷涂carstrucks清单中的任何东西。

Now, the rest assumes I understand your requirements correctly... 现在,其余的假设我都正确理解了您的要求...

Next, we need some way to add new vehicles to the lists... 接下来,我们需要某种方式将新车添加到列表中...

Not know how you intended to update the component, I wrote this simple method that generates a random number between 0-4 and on 1 it creates a Car and on 3 it generates a Truck , you can change this to whatever you like. 不知道您打算如何更新组件,我写了这个简单的方法,它会生成一个0-4之间的随机数,在1它会生成Car ,在3它会生成Truck ,您可以将其更改为任意值。 It checks to see if there is available space in the lists for the new vehicle first before creating them... 它会先检查列表中是否有新车可用的空间,然后再创建它们...

public void addNewVehicle() {

    int value = (int) Math.round(Math.random() * 5);

    if (value == 1) {
        if (cars.size() < 10) {
            cars.add(new Car(getSize()));
        }
    } else if (value == 3) {
        if (trucks.size() < 10) {
            trucks.add(new Truck(getSize()));
        }
    } else {
        System.out.println("No new toys");
    }
    repaint();
}

To trigger an update, I use a Swing Timer , which called the addNewVehicle method every second... 为了触发更新,我使用了Swing Timer ,它addNewVehicle调用一次addNewVehicle方法...

Timer timer = new Timer(1000, new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        component.addNewVehicle();
        runningCount.setText(component.toString());
    }

});
timer.start();

Adding in the randomised nature of the addNewVehicle method, this means you won't see a vehicle added every second. 加上addNewVehicle方法的addNewVehicle ,这意味着您不会看到每秒增加一辆载具。 This also updates the runningCount label at the same time, keeping it in sync... 这还将同时更新runningCount标签,使其保持同步...

Now, given the nature of painting process, I changed the way your Truck and Car paint, instead of randomizing the color each time they are drawn, I randomized the color when each instance is created instead 现在,考虑到绘画过程的本质,我更改了“ Truck和“ Car油漆的方式,而不是在每次绘制时随机化颜色,而是在创建每个实例时随机化颜色

public class Car extends Vehicle {

    private int xLeft;
    private int yTop;
    private Color color;

    public Car(Dimension size) {
        xLeft = (int) Math.round((Math.random() * size.width - 60));
        yTop = (int) Math.round((Math.random() * size.height - 10));

        Random rand = new Random();

        float red = rand.nextFloat();
        float green = rand.nextFloat();
        float blue = rand.nextFloat();

        color = new Color(red, green, blue);
    }

    @Override
    public void draw(Graphics g2) {

        Rectangle body = new Rectangle(xLeft, yTop + 10, 60, 10);
        Ellipse2D.Double frontTire = new Ellipse2D.Double(xLeft + 10, yTop + 20, 10, 10);
        Ellipse2D.Double rearTire = new Ellipse2D.Double(xLeft + 40, yTop + 20, 10, 10);

        Point2D.Double r1 = new Point2D.Double(xLeft + 10, yTop + 10);
        Point2D.Double r2 = new Point2D.Double(xLeft + 20, yTop);
        Point2D.Double r3 = new Point2D.Double(xLeft + 40, yTop);
        Point2D.Double r4 = new Point2D.Double(xLeft + 50, yTop + 10);

        Line2D.Double frontWindshield = new Line2D.Double(r1, r2);
        Line2D.Double roofTop = new Line2D.Double(r2, r3);
        Line2D.Double rearWindshield = new Line2D.Double(r3, r4);

        ((Graphics2D) g2).setColor(color);

        ((Graphics2D) g2).fill(body);
        ((Graphics2D) g2).fill(frontTire);
        ((Graphics2D) g2).fill(rearTire);

        ((Graphics2D) g2).draw(body);
        ((Graphics2D) g2).draw(frontTire);
        ((Graphics2D) g2).draw(rearTire);
        ((Graphics2D) g2).draw(frontWindshield);
        ((Graphics2D) g2).draw(rearWindshield);
        ((Graphics2D) g2).draw(roofTop);

    }

}

public class Truck extends Vehicle {

    private int xLeft;
    private int yTop;
    private Color color;

    public Truck(Dimension size) {
        xLeft = (int) Math.round((Math.random() * size.width - 60));
        yTop = (int) Math.round((Math.random() * size.height - 20));
        Random rand = new Random();

        float red = rand.nextFloat();
        float green = rand.nextFloat();
        float blue = rand.nextFloat();

        color = new Color(red, green, blue);
    }

    @Override
    public void draw(Graphics g2) {

        Rectangle body = new Rectangle(xLeft + 22, yTop + 10, 60, 20);
        Rectangle topCab = new Rectangle(xLeft, yTop + 10, 20, 10);
        Rectangle bottomCab = new Rectangle(xLeft, yTop + 20, 20, 10);
        Ellipse2D.Double frontTire = new Ellipse2D.Double(xLeft + 6, yTop + 30, 10, 10);
        Ellipse2D.Double midTire = new Ellipse2D.Double(xLeft + 25, yTop + 30, 10, 10);
        Ellipse2D.Double mid2Tire = new Ellipse2D.Double(xLeft + 35, yTop + 30, 10, 10);
        Ellipse2D.Double backTire = new Ellipse2D.Double(xLeft + 55, yTop + 30, 10, 10);
        Ellipse2D.Double back2Tire = new Ellipse2D.Double(xLeft + 65, yTop + 30, 10, 10);

        ((Graphics2D) g2).setColor(color);

        ((Graphics2D) g2).fill(body);
        ((Graphics2D) g2).fill(bottomCab);
        ((Graphics2D) g2).fill(frontTire);
        ((Graphics2D) g2).fill(midTire);
        ((Graphics2D) g2).fill(mid2Tire);
        ((Graphics2D) g2).fill(backTire);
        ((Graphics2D) g2).fill(back2Tire);

        ((Graphics2D) g2).draw(body);
        ((Graphics2D) g2).draw(topCab);
        ((Graphics2D) g2).draw(bottomCab);
        ((Graphics2D) g2).draw(frontTire);
        ((Graphics2D) g2).draw(midTire);
        ((Graphics2D) g2).draw(mid2Tire);
        ((Graphics2D) g2).draw(backTire);
        ((Graphics2D) g2).draw(back2Tire);
    }
}

Now, cause that could be some effort to piece back together, this is the code I used to test it... 现在,可能需要花费一些精力才能重新组合起来,这是我用来测试的代码...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                final VehicleComponent component = new VehicleComponent();
                frame.add(component);
                final JLabel runningCount = new JLabel(component.toString());
                frame.add(runningCount, BorderLayout.SOUTH);

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                Timer timer = new Timer(1000, new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        component.addNewVehicle();
                        runningCount.setText(component.toString());
                    }

                });
                timer.start();
            }
        });
    }

    public abstract class Vehicle {

        public abstract void draw(Graphics g2);
    }

    public class Car extends Vehicle {

        private int xLeft;
        private int yTop;
        private Color color;

        public Car(Dimension size) {
            xLeft = (int) Math.round((Math.random() * size.width - 60));
            yTop = (int) Math.round((Math.random() * size.height - 10));

            Random rand = new Random();

            float red = rand.nextFloat();
            float green = rand.nextFloat();
            float blue = rand.nextFloat();

            color = new Color(red, green, blue);
        }

        @Override
        public void draw(Graphics g2) {

            Rectangle body = new Rectangle(xLeft, yTop + 10, 60, 10);
            Ellipse2D.Double frontTire = new Ellipse2D.Double(xLeft + 10, yTop + 20, 10, 10);
            Ellipse2D.Double rearTire = new Ellipse2D.Double(xLeft + 40, yTop + 20, 10, 10);

            Point2D.Double r1 = new Point2D.Double(xLeft + 10, yTop + 10);
            Point2D.Double r2 = new Point2D.Double(xLeft + 20, yTop);
            Point2D.Double r3 = new Point2D.Double(xLeft + 40, yTop);
            Point2D.Double r4 = new Point2D.Double(xLeft + 50, yTop + 10);

            Line2D.Double frontWindshield = new Line2D.Double(r1, r2);
            Line2D.Double roofTop = new Line2D.Double(r2, r3);
            Line2D.Double rearWindshield = new Line2D.Double(r3, r4);

            ((Graphics2D) g2).setColor(color);

            ((Graphics2D) g2).fill(body);
            ((Graphics2D) g2).fill(frontTire);
            ((Graphics2D) g2).fill(rearTire);

            ((Graphics2D) g2).draw(body);
            ((Graphics2D) g2).draw(frontTire);
            ((Graphics2D) g2).draw(rearTire);
            ((Graphics2D) g2).draw(frontWindshield);
            ((Graphics2D) g2).draw(rearWindshield);
            ((Graphics2D) g2).draw(roofTop);

        }

    }

    public class Truck extends Vehicle {

        private int xLeft;
        private int yTop;
        private Color color;

        public Truck(Dimension size) {
            xLeft = (int) Math.round((Math.random() * size.width - 60));
            yTop = (int) Math.round((Math.random() * size.height - 20));
            Random rand = new Random();

            float red = rand.nextFloat();
            float green = rand.nextFloat();
            float blue = rand.nextFloat();

            color = new Color(red, green, blue);
        }

        @Override
        public void draw(Graphics g2) {

            Rectangle body = new Rectangle(xLeft + 22, yTop + 10, 60, 20);
            Rectangle topCab = new Rectangle(xLeft, yTop + 10, 20, 10);
            Rectangle bottomCab = new Rectangle(xLeft, yTop + 20, 20, 10);
            Ellipse2D.Double frontTire = new Ellipse2D.Double(xLeft + 6, yTop + 30, 10, 10);
            Ellipse2D.Double midTire = new Ellipse2D.Double(xLeft + 25, yTop + 30, 10, 10);
            Ellipse2D.Double mid2Tire = new Ellipse2D.Double(xLeft + 35, yTop + 30, 10, 10);
            Ellipse2D.Double backTire = new Ellipse2D.Double(xLeft + 55, yTop + 30, 10, 10);
            Ellipse2D.Double back2Tire = new Ellipse2D.Double(xLeft + 65, yTop + 30, 10, 10);

            ((Graphics2D) g2).setColor(color);

            ((Graphics2D) g2).fill(body);
            ((Graphics2D) g2).fill(bottomCab);
            ((Graphics2D) g2).fill(frontTire);
            ((Graphics2D) g2).fill(midTire);
            ((Graphics2D) g2).fill(mid2Tire);
            ((Graphics2D) g2).fill(backTire);
            ((Graphics2D) g2).fill(back2Tire);

            ((Graphics2D) g2).draw(body);
            ((Graphics2D) g2).draw(topCab);
            ((Graphics2D) g2).draw(bottomCab);
            ((Graphics2D) g2).draw(frontTire);
            ((Graphics2D) g2).draw(midTire);
            ((Graphics2D) g2).draw(mid2Tire);
            ((Graphics2D) g2).draw(backTire);
            ((Graphics2D) g2).draw(back2Tire);
        }
    }

    public class VehicleComponent extends JComponent {

        private int x;
        private int y;

        private List<Car> cars;
        private List<Truck> trucks;

        private Random rnd = new Random();

        public VehicleComponent() {
            cars = new ArrayList<>(25);
            trucks = new ArrayList<>(25);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            for (Car car : cars) {
                car.draw(g2);
            }
            for (Truck truck : trucks) {
                truck.draw(g2);
            }
        }

        public void addNewVehicle() {

            int value = (int) Math.round(Math.random() * 5);

            if (value == 1) {
                if (cars.size() < 10) {
                    cars.add(new Car(getSize()));
                }
            } else if (value == 3) {
                if (trucks.size() < 10) {
                    trucks.add(new Truck(getSize()));
                }
            } else {
                System.out.println("No new toys");
            }
            repaint();
        }

        @Override
        public String toString() {
            return "Trucks: " + trucks.size() + ", Cars: " + cars.size();
        }

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM